The downside of message passing is debugging. No call stack so you can't trace things back to their source.
I use an additional message parameter, automatically inserted and maintained by the framework, which is a list of the messages (FIPA style operation + parameters) from the originating agent forwards to the point of debugging. This gets voluminous and is gated by debug levels.