You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inferred message identity for sagas needs to be able to infer from the saga-id header too #4484
Hi Jeremy! Here's a little bit of write-up from our discussion the other day:
Message partitioning for sagas allows us to use the scatter-gather style of work, particularly useful in batch processing, without paying the cost of concurrency-related retries.
Currently, UseInferredMessageGrouping requires the saga ID to be explicitly provided in response messages, so that routing works correctly.
This works fine if the handlers that send the responses belong to the same saga. This detail is contained within the saga "module" itself and the responsibility of the saga author to get right. However, if the handlers belong elsewhere (ex: domain logic handlers), then they need to become aware of the fact that they may participate in a saga, and places the burden on those handlers to remember to include the saga ID explicitly in their response - otherwise they break routing back in the saga.
A saga-aware domain handler would look like this:
publicstatic(Events,OutgoingMessages)Handle(DoSomeDomainWorkcommand){// ... business logic that may emit events ...varmessages=newOutgoingMessages();if(command.SagaIdis{}sagaId/*alternatively check the Envelope*/)// only when the request came from a saga: separate issue/consideration/discussion, see note belowmessages.Add(newSomeDomainWorkCompleted(sagaId/* must remember to copy this explicitly */,/* extra info */));return(events,messages);}
Where header-based saga ID inference really shines, however, is when it comes to fault events. The user cannot edit/customize fault events and never gets the chance to add a saga ID field in there. Deriving it from the header would fix this issue.
Note on the conditional response message bit: even with the above fix, domain handlers will still need to be saga-aware, because cascading responses when not used by a saga will still trigger the saga handler of that response. Messages with no saga ID (whether header or property) throw with a IndeterminateSagaStateIdException. While domain handlers can optionally emit responses based on the presence of a saga ID, Fault events don't have that option. So a faulted domain handler used by a saga will cause the saga to throw if the fault happened while processing a message not sent to the handler by the saga. This could be solved with a IdNotProvided hook in a similar fashion to NotFound that gives the user the chance to handle such messages.
@GeorgeF0 Hey, has your bunch thought anymore about a possible engagement around this and some of the other things we talked about the other week? I thought about trying to take this in for a "quick" release today and remembered that it's a little bit involved, so it's time to follow up with you.
Activity
jeremydmiller commentedon Sep 18, 2026
Also account for
Fault<T>messages in this case as well too.GeorgeF0 commentedon Sep 22, 2026
Hi Jeremy! Here's a little bit of write-up from our discussion the other day:
Message partitioning for sagas allows us to use the scatter-gather style of work, particularly useful in batch processing, without paying the cost of concurrency-related retries.
Currently,
UseInferredMessageGroupingrequires the saga ID to be explicitly provided in response messages, so that routing works correctly.This works fine if the handlers that send the responses belong to the same saga. This detail is contained within the saga "module" itself and the responsibility of the saga author to get right. However, if the handlers belong elsewhere (ex: domain logic handlers), then they need to become aware of the fact that they may participate in a saga, and places the burden on those handlers to remember to include the saga ID explicitly in their response - otherwise they break routing back in the saga.
A saga-aware domain handler would look like this:
Where header-based saga ID inference really shines, however, is when it comes to fault events. The user cannot edit/customize fault events and never gets the chance to add a saga ID field in there. Deriving it from the header would fix this issue.
Note on the conditional response message bit: even with the above fix, domain handlers will still need to be saga-aware, because cascading responses when not used by a saga will still trigger the saga handler of that response. Messages with no saga ID (whether header or property) throw with a
IndeterminateSagaStateIdException. While domain handlers can optionally emit responses based on the presence of a saga ID, Fault events don't have that option. So a faulted domain handler used by a saga will cause the saga to throw if the fault happened while processing a message not sent to the handler by the saga. This could be solved with aIdNotProvidedhook in a similar fashion toNotFoundthat gives the user the chance to handle such messages.jeremydmiller commentedon Sep 29, 2026
@GeorgeF0 Hey, has your bunch thought anymore about a possible engagement around this and some of the other things we talked about the other week? I thought about trying to take this in for a "quick" release today and remembered that it's a little bit involved, so it's time to follow up with you.