Skip to content

CHR0018: Constraint Define() must not contain imperative code

The Define() method of a class implementing IConstraint must not contain imperative statements such as if/else, loops, variable declarations, or assignments. Constraint definitions only declare rules; they do not execute.

Error

using Cratis.Chronicle.Events;
using Cratis.Chronicle.Events.Constraints;
[EventType]
public record Chr0018UserRegistered;
public class Chr0018UniqueEmailConstraint : IConstraint
{
public bool SomeCondition { get; init; }
// CHR0018: Define must not contain conditional logic
public void Define(IConstraintBuilder builder)
{
if (SomeCondition)
{
builder.Unique<Chr0018UserRegistered>();
}
}
}
using Cratis.Chronicle.Events;
using Cratis.Chronicle.Events.Constraints;
[EventType]
public record Chr0018UserRegisteredFixed;
public class Chr0018UniqueEmailConstraintFixed : IConstraint
{
// Now valid - unconditional
public void Define(IConstraintBuilder builder) =>
builder.Unique<Chr0018UserRegisteredFixed>();
}

The Define() method is called once at registration time to declare constraint rules. The resulting definition is serialized and sent to the server. Imperative code such as conditionals or loops creates non-determinism: different runs could produce different constraint definitions, breaking consistency.

  • CHR0017: Constraint must not have side effects
  • CHR0016: Projection Define() must not contain imperative code