CHR0001: Event type must have an event declaration attribute
Rule Description
Section titled “Rule Description”Types that are appended to event sequences must be marked with [EventType] or [EventTypeGenerationFor<T>], or explicitly registered as event types. Use [EventType] for the current event schema and [EventTypeGenerationFor<T>] for a previous generation of that event type. This ensures that all events in the event store are properly identified and can be correctly deserialized. The rule checks the event argument of Append and AppendMany, including calls with named arguments. Events passed inside EventForEventSourceId wrappers are typed as object and are not checked at compile time; the overload’s optional tags, correlation ID, and concurrency scopes are not event types.
Severity
Section titled “Severity”Error
Example
Section titled “Example”Violation
Section titled “Violation”using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;
// Missing [EventType] attributepublic record Chr0001UserCreated(string Username, string Email);
public class Chr0001UserService(IEventSequence eventSequence){ public Task CreateUser(EventSourceId userId, string username, string email) => // CHR0001: Type 'Chr0001UserCreated' must be marked with [EventType] or [EventTypeGenerationFor<T>] when appended to an event sequence eventSequence.Append(userId, new Chr0001UserCreated(username, email));}using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;
[EventType]public record Chr0001UserCreatedFixed(string Username, string Email);
public class Chr0001UserServiceFixed(IEventSequence eventSequence){ public Task CreateUser(EventSourceId userId, string username, string email) => // Now valid eventSequence.Append(userId, new Chr0001UserCreatedFixed(username, email));}Appending a previous generation
Section titled “Appending a previous generation”For a current event record KnownEvent marked with [EventType], declare its previous schema as [EventTypeGenerationFor<KnownEvent>(1)] public record PreviousEvent(string Name);. Then append that schema with await eventStore.EventLog.Append(eventSourceId, new PreviousEvent("Ada"));. CHR0001 accepts the previous-generation marker without requiring [EventType] on PreviousEvent; do not combine the two attributes.
Quick Fix
Section titled “Quick Fix”The analyzer provides a code fix that automatically:
- Adds the
[EventType]attribute to the event type - Adds the required using directive if not already present
Why This Rule Exists
Section titled “Why This Rule Exists”The [EventType] attribute is crucial for Chronicle’s event handling:
- It uniquely identifies the event type in the event store
- It enables proper event serialization and deserialization
- It allows Chronicle to track event type generations and schemas
- It ensures type safety when working with events