Error Codes Reference
Every validation failure in DynamicWhere.ex throws a LogicException (which inherits from Exception). The Message property carries one of the 22 stable error strings listed below, so you can pattern‑match them in middleware and surface meaningful problems to API callers.
How errors are raised
Validation runs eagerly — before any expression tree is built or any SQL is emitted. If your Filter, Segment, Summary, ConditionGroup, GroupBy, or PageBy shape is invalid, the corresponding extension method throws synchronously (even on the async overloads, the throw happens before the first await). The thrown type is always LogicException and the message is always one of the rows in the table below.
try / catch (LogicException ex) and map it to a 400 Bad Request with the message as the validation reason. Other exception types should bubble up as 500s.app.MapPost("/customers/search", async (Filter filter, AppDbContext db) =>
{
try
{
var result = await db.Customers.ToListAsync(filter);
return Results.Ok(result);
}
catch (LogicException ex)
{
// ex.Message is one of the stable error codes below
return Results.BadRequest(new { error = ex.Message });
}
});All 22 error codes
Codes wrapped in (parens) are parameterized — the bracketed token in the message is replaced at runtime with the offending operator, alias, aggregator, type, or field name.
| Error Code | Message | Triggered When |
|---|---|---|
SetsUniqueSort | ListOfConditionsSetsMustHasUniqueSortValue | Duplicate Sort in ConditionSets |
ConditionsUniqueSort | AnyListOfConditionsMustHasUniqueSortValue | Duplicate Sort in Conditions |
SubConditionsGroupsUniqueSort | AnyListOfSubConditionsGroupsMustHasUniqueSortValue | Duplicate Sort in SubConditionGroups |
RequiredIntersection | ConditionsSetOfIndex[1-N]MustHasIntersection | Missing Intersection on set index 1+ |
InvalidField | ConditionMustHasValidFieldName | Empty or invalid field name |
InvalidValue | ConditionValuesAreNullOrWhiteSpace | Null / whitespace value |
RequiredValues | ConditionWithOperator[In-IIn-NotIn-INotIn]MustHasOneOrMoreValues | In / NotIn with 0 values |
NotRequiredValues | ConditionWithOperator[IsNull-IsNotNull]MustHasNoValues | IsNull / IsNotNull with values |
RequiredTwoValue | ConditionWithOperator[Between-NotBetween]MustHasOnlyTwoValues | Between without exactly 2 values |
RequiredOneValue(op) | ConditionWithOperator[{op}]MustHasOnlyOneValue | Single‑value operator with wrong count |
InvalidPageNumber | PageNumberMustBeGreaterThanZero | PageNumber ≤ 0 |
InvalidPageSize | PageSizeMustBeGreaterThanZero | PageSize ≤ 0 |
MustHaveFields | MustHasFields | Empty fields list in Select |
InvalidFormat | InvalidFormat | Value doesn't parse for declared DataType |
InvalidAlias | AggregationMustHasValidAlias | Empty or dotted alias |
GroupByMustHaveFields | GroupByMustHasAtLeastOneField | GroupBy with no fields |
GroupByFieldsMustBeUnique | GroupByFieldsMustBeUnique | Duplicate GroupBy fields |
GroupByFieldCannotBeComplexType | GroupByFieldCannotBeComplexType | Non‑simple GroupBy field |
GroupByFieldCannotBeCollection | GroupByFieldCannotBeCollectionType | Collection GroupBy field |
AggregationFieldMustBeSimpleType | AggregationFieldMustBeSimpleType | Complex aggregation field |
AggregationFieldCannotBeCollection | AggregationFieldCannotBeCollectionType | Collection aggregation field |
AggregationAliasesMustBeUnique | AggregationAliasesMustBeUnique | Duplicate aliases |
AggregationAliasCannotBeGroupByField(alias) | AggregationAlias[{alias}]CannotBeUsedInGroupByFields | Alias clashes with a GroupBy field |
UnsupportedAggregatorForType(agg, type) | Aggregator[{agg}]IsNotSupportedForFieldType[{type}] | Invalid aggregator for the field's type |
SummaryOrderFieldMustExistInGroupByOrAggregate(f) | SummaryOrderField[{f}]MustExistInGroupByFieldsOrAggregateByAliases | Order on a non‑grouped, non‑aggregated field |
HavingFieldMustExistInAggregateByAlias(f) | HavingField[{f}]MustExistInAggregateByAliases | Having references an unknown alias |
Where each error lives
Each error is raised by a specific validation entry point. Follow the link for the full validation rules and the exact shape that triggers each code:
- Condition validation →
InvalidField,InvalidValue,RequiredValues,NotRequiredValues,RequiredTwoValue,RequiredOneValue(op),InvalidFormat. - ConditionGroup validation →
SetsUniqueSort,ConditionsUniqueSort,SubConditionsGroupsUniqueSort,RequiredIntersection. - Page validation →
InvalidPageNumber,InvalidPageSize. - GroupBy validation →
MustHaveFields,GroupByMustHaveFields,GroupByFieldsMustBeUnique,GroupByFieldCannotBeComplexType,GroupByFieldCannotBeCollection. - Summary validation →
InvalidAlias,AggregationFieldMustBeSimpleType,AggregationFieldCannotBeCollection,AggregationAliasesMustBeUnique,AggregationAliasCannotBeGroupByField(alias),UnsupportedAggregatorForType(agg, type),SummaryOrderFieldMustExistInGroupByOrAggregate(f),HavingFieldMustExistInAggregateByAlias(f). - Segment validation → inherits all
ConditionGroup+Pageerrors and additionally enforcesRequiredIntersectionfor sets at index 1 and above.
See also
- Breaking Changes & Known Limitations → behaviour that is not an error but may surprise you.
- Filter → the most common entry point that triggers these validations.