Well said. I've used the second pattern you described as well. If I find myself in a situation where I'm tempted to treat the message as mutable, it usually indicates I've hit the point where I need to (potentially) use some sort of transformation pipeline, and the steps in that transformation should ideally be encapsulated inside a component and not publicly exposed on the bus itself.