CommandExecutionException when sending two simultaneous commands in saga

Hello,

I’m attempting to create a proof-of-concept saga that creates two different aggregate types in response to an event. Unfortunately whenever I run this with both commands being sent, the CreateAccountAttemptCommand fails with the following message:

Command ‘com.x.y.command.CreateAccountAttemptCommand’ resulted in org.axonframework.commandhandling.CommandExecutionException(No such field com.x.y.command.CreateAccountAttemptCommand.attemptId

If I only send one or the other they go through successfully, and this issue only occurs with the Account command, not Customer. The CreateAccountAttemptCommand has no associated aggregate, as it is handled by an external CommandHandler which then emits AccountCreationSuccessful. In theory, in the saga event handler we’d then actually create the aggregate, but for clarity I’ve taken that out. Here are a few snippets to hopefully inform the issue.

@Data
public class CreateAccountAttemptCommand {

    @RoutingKey
    private final String attemptId;
    private final String userId;
    private final String name;
    private final String lastName;

    public CreateAccountAttemptCommand(String userId, String attemptId) {
        this.userId = userId;
        this.name = "Test";
        this.lastName = "User";
        this.attemptId = attemptId;
    }
}

@Data
@AllArgsConstructor
public class CreateCustomerCommand {
    @TargetAggregateIdentifier
    private String customerId;
    private String firstName;
    private String lastName;
}

@Saga
public class CreateAccountSaga {
    private boolean accountCreated = false;
    private boolean customerCreated = false;

    @Autowired
    transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "userId")
    public void handle(AccountRequestedEvent event) {
        setup();

        String customerId = UUID.randomUUID().toString();
        String attemptId = UUID.randomUUID().toString();
        SagaLifecycle.associateWith("customerId", customerId);
        SagaLifecycle.associateWith("attemptId", attemptId);
        commandGateway.send(new CreateAccountAttemptCommand(event.getUserId(), attemptId));
        commandGateway.send(new CreateCustomerCommand(customerId, "Tom", "A"));
    }

    @SagaEventHandler(associationProperty = "attemptId")
    public void handle(AccountCreationAttemptSuccessfulEvent event) {
        accountCreated = true;
        if (customerCreated) { SagaLifecycle.end(); }
    }

    @SagaEventHandler(associationProperty = "customerId")
    public void handle(CustomerCreatedEvent event) {
        customerCreated = true;
        if (accountCreated) { SagaLifecycle.end(); }
    }

    public void setup() {
        commandGateway.registerDispatchInterceptor(new CommandDispatchInterceptor());
    }
}

Update: I’ve resolved this. No wonder there aren’t many examples of this error occurring. Turns out another machine was connecting to my hostname on this network to share the axon server (running on Docker on my local machine). Once I gave this saga enough traffic, it would load balance between our two machines and the other was woefully out of date, i.e. unable to handle that command with that signature. For anyone who needs a (likely obvious) debugging tip, what helped me find it was a combination of the UI under “Commands” showing multiple hosts connected, and the “location” section under each command when you enable debug logs via:

logging.level.org.axonframework.*=DEBUG

`
Received command response [message_identifier: “873f59cb-eda4-4114-9c97-f712367108b5”
error_code: “AXONIQ-4002”
error_message {
message: “No such field com.x.y.command.CreateAccountAttemptCommand.creationAttemptId\n---- Debugging information ----\nmessage : No such field com.x.y.command.CreateAccountAttemptCommand.creationAttemptId\nfield : creationAttemptId\nclass : com.x.y.command.CreateAccountAttemptCommand\nrequired-type : com.x.y.command.CreateAccountAttemptCommand\nconverter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter\npath : /com.x.y.command.CreateAccountAttemptCommand/creationAttemptId\nline number : 1\nversion : 1.4.11.1\n-------------------------------”
location: “13849@ip-a-b-c-d.ec2.internal”
details: “No such field com.x.y.command.CreateAccountAttemptCommand.creationAttemptId\n---- Debugging information ----\nmessage : No such field com.x.y.command.CreateAccountAttemptCommand.creationAttemptId\nfield : creationAttemptId\nclass : com.x.y.command.CreateAccountAttemptCommand\nrequired-type : com.x.y.command.CreateAccountAttemptCommand\nconverter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter\npath : /com.x.y.command.CreateAccountAttemptCommand/creationAttemptId\nline number : 1\nversion : 1.4.11.1\n-------------------------------”
}
meta_data {
key: “traceId”
value {
text_value: “81ef65b3-382a-4ce8-ac41-020ea44e6e5c”
}
}
meta_data {
key: “correlationId”
value {
text_value: “25ac2e63-1d84-4d77-bf0b-ce22af64650f”
}
}
request_identifier: “25ac2e63-1d84-4d77-bf0b-ce22af64650f”
]

`