On the “Aggregate identifier must be non-null after applying an event” error message

by Wilco KoornJanuary 18, 2021
Photo by Digital Design Journal on Pinterest

Even when you have been developing applications using the Axon framework for years, you still come across learnings that are worthwhile sharing. Today I learned such a lesson and I would like to share it with you.

I was adding a new property to an Entity in my application and updated the Revision of the Create and Update events. After, I wrote an Upcaster and ran a Reset to replay all my events and did the actual update of the Entity in the View Models. This is Axon business as usual. Next, I inspected my View Model database and was happy to see the new property present with the default value I gave it in the Upcaster. Cool: Done! Uhhhh. No.

When I tested updating the value of the new property through the GUI, it failed. Excuse me? It’s a simple new Boolean value. I looked at the network traffic between the browser and the backend and saw the GUI communicating the new property correctly. I also put a breakpoint in my REST Controller in the backend. All OK. However, then I spotted a stacktrace and received this message:

org.axonframework.eventsourcing.IncompatibleAggregateException: Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.

Initially, I couldn’t understand what was going on. I have been adapting an Entity in my application for ages, therefore I was absolutely convinced I handled it’s Aggregate IDs properly. There was something else wrong, but what? What I discovered was logical in a way, but still unexpected: the root cause of the problem was the switching of the git branches. This is what really happened:

The day before I had made another change on the same Aggregate, but I was working on another git branch. That change did not per se require an Upcaster to make my application run well. I added a sub-property in the following way:

AGGREGATE 
        - property 1
        - property 2
                - sub property 2.a
                - sub property 2.b
                - sub property 2.c   <— added yesterday
        - property 3

As this branch was under review, I switched back to ‘master’ and made another branch today:

AGGREGATE
        - property 1
        - property 2
                - sub property 2.a
                - sub property 2.b
        - property 3
        - property 4                     <— added today

Note that this did NOT contain the sub property 2.c yet. And it should not, as this was under review. But now I found myself in trouble because I needed to test the changes I was experimenting with yesterday. As a result, there were Update events in my event store since yesterday containing the sub property 2.c.

All updates on these Aggregates were failing for a perfectly logical reason: when Axon was applying today’s update event, it loaded the Aggregate’s state. To do so it loaded all events with the same Aggregate ID, found an Update event containing sub property 2.c, and failed. It gave an  “IncompatibleAggregateException” message. In most cases, such an Exception is caused by improperly setting the Aggregate ID, but not in my case.

To solve the problem you may, of course, consider merging yesterday’s branch into the one of today, but that makes the branches dependent. As an alternative, you can delete events today, but that makes the branches dependent. As an alternative, you can delete events containing the sub property 2.c from the event store. This solution is more viable because you can’t delete events when using the Axon Server and because it forbids you to get a recent backup and restore it.

Conclusion
When you see the Axon error message “org.axonframework.eventsourcing.IncompatibleAggregateException: Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.”  think of ID initialisation as a first solution. Then also remember you may have incompatible events in your event store due to branch switching in development.