Skip to main content
The ErrorOrX generator and analyzer emit diagnostics to help catch issues at compile time.

Endpoint Diagnostics

Handler Structure

IDSeverityDescription
EOE001ErrorInvalid return type - must return ErrorOr<T>
EOE002ErrorHandler must be static
EOE017ErrorAnonymous return type not supported
EOE020ErrorInaccessible type (private/protected) in endpoint
EOE021ErrorType parameter not supported in return type

Route Validation

IDSeverityDescription
EOE003ErrorRoute parameter not bound to method parameter
EOE004ErrorDuplicate route pattern detected
EOE005ErrorInvalid route pattern syntax
EOE023WarningRoute constraint type mismatch (e.g., {id:int} with string param)

Parameter Binding

IDSeverityDescription
EOE006ErrorMultiple body sources on single endpoint
EOE009Warning[FromBody] on GET/DELETE method
EOE011ErrorInvalid [FromRoute] type
EOE012ErrorInvalid [FromQuery] type
EOE013ErrorInvalid [AsParameters] type
EOE014Error[AsParameters] type has no accessible constructor
EOE016ErrorInvalid [FromHeader] type
EOE018ErrorNested [AsParameters] not supported
EOE019ErrorNullable [AsParameters] not supported
EOE025ErrorAmbiguous parameter binding (GET/DELETE + complex type)

AOT & Serialization

IDSeverityDescription
EOE007WarningType not AOT-serializable
EOE030InfoToo many result types for Results<> union (max 6)
EOE032WarningUnknown error factory method
EOE033ErrorUndocumented interface call
EOE040WarningMissing CamelCase JSON policy on user’s JsonSerializerContext

Response Attributes

IDSeverityDescription
EOE010Warning[AcceptedResponse] on GET/DELETE method

API Versioning Diagnostics

IDSeverityDescription
EOE050Error[ApiVersionNeutral] and [MapToApiVersion] are mutually exclusive
EOE051Error[MapToApiVersion] references undeclared version
EOE052ErrorAsp.Versioning.Http package not referenced
EOE053WarningEndpoint missing versioning when others use it
EOE054ErrorInvalid version format

Common Fixes

EOE001: Invalid Return Type

// ❌ Wrong
[Get("/todos")]
public static List<Todo> GetAll() => _db.GetAll();

// ✅ Correct
[Get("/todos")]
public static ErrorOr<List<Todo>> GetAll() => _db.GetAll();

EOE002: Handler Must Be Static

// ❌ Wrong
public class TodoEndpoints
{
    [Get("/todos")]
    public ErrorOr<List<Todo>> GetAll() => ...
}

// ✅ Correct
public static class TodoEndpoints
{
    [Get("/todos")]
    public static ErrorOr<List<Todo>> GetAll() => ...
}

EOE003: Route Parameter Not Bound

// ❌ Wrong - 'id' in route but not in params
[Get("/todos/{id}")]
public static ErrorOr<Todo> Get() => ...

// ✅ Correct
[Get("/todos/{id}")]
public static ErrorOr<Todo> Get(int id) => ...

EOE004: Duplicate Route

// ❌ Wrong - same route pattern
[Get("/todos/{id}")]
public static ErrorOr<Todo> GetById(int id) => ...

[Get("/todos/{todoId}")]  // EOE004: Duplicate of /todos/{id}
public static ErrorOr<Todo> GetByTodoId(int todoId) => ...

EOE025: Ambiguous Parameter Binding

// ❌ Wrong - complex type on GET without explicit binding
[Get("/todos")]
public static ErrorOr<List<Todo>> Search(SearchFilter filter) => ...

// ✅ Option 1: Explicit FromQuery
[Get("/todos")]
public static ErrorOr<List<Todo>> Search([FromQuery] SearchFilter filter) => ...

// ✅ Option 2: AsParameters
[Get("/todos")]
public static ErrorOr<List<Todo>> Search([AsParameters] SearchFilter filter) => ...

// ✅ Option 3: FromBody (if intentional)
[Get("/todos")]
public static ErrorOr<List<Todo>> Search([FromBody] SearchFilter filter) => ...

EOE040: Missing CamelCase Policy

// ❌ Wrong - no naming policy
[JsonSerializable(typeof(Todo))]
internal partial class AppJsonContext : JsonSerializerContext { }

// ✅ Correct
[JsonSourceGenerationOptions(
    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Todo))]
internal partial class AppJsonContext : JsonSerializerContext { }