---
title: 'CHR0002: Declarative projection event type must have [EventType] attribute'
---

## Rule Description

Generic type arguments in declarative projections that reference event types must be marked with the `[EventType]` attribute.

## Severity

Error

## Example

### Violation

```csharp
// Missing [EventType] attribute
public record OrderCreated(Guid OrderId, decimal Amount);

public class OrderProjection : IProjectionFor<OrderReadModel>
{
    public void Define(IProjectionBuilderFor<OrderReadModel> builder)
    {
        // CHR0002: Type 'OrderCreated' must be marked with [EventType] attribute
        builder.From<OrderCreated>(e => e.OrderId)
            .Set(m => m.Id).To(e => e.OrderId)
            .Set(m => m.Amount).To(e => e.Amount);
    }
}
```

### Fix

```csharp
using Cratis.Chronicle.Concepts.Events;

[EventType]
public record OrderCreated(Guid OrderId, decimal Amount);

public class OrderProjection : IProjectionFor<OrderReadModel>
{
    public void Define(IProjectionBuilderFor<OrderReadModel> builder)
    {
        // Now valid
        builder.From<OrderCreated>(e => e.OrderId)
            .Set(m => m.Id).To(e => e.OrderId)
            .Set(m => m.Amount).To(e => e.Amount);
    }
}
```

## Quick Fix

The analyzer provides a code fix that automatically adds the `[EventType]` attribute to the referenced type.

## Why This Rule Exists

Declarative projections define how events are projected into read models. All event types used in these projections must be properly identified to ensure:
- Correct event routing and handling
- Proper schema tracking
- Type-safe projection definitions

## Related Rules

- [CHR0001](/chronicle/code-analysis/chr0001/): Event sequence append operations
- [CHR0003](/chronicle/code-analysis/chr0003/): Model bound projection attributes
