usememos/memos · error
comprehension range must be a field identifier
Error message
comprehension range must be a field identifier
What it means
buildComprehensionCondition translates CEL comprehensions (exists/all over a list field, e.g. tag.exists(t, t.startsWith("w"))). The iteration range must be a bare schema field identifier; comp.IterRange.GetIdentExpr() returning nil (a call, literal, or select expression as the range) fails here.
Source
Thrown at internal/filter/parser.go:814
seen[v] = true
out = append(out, v)
}
}
return out
}
// buildComprehensionCondition handles CEL comprehension expressions (exists, all, etc.).
func buildComprehensionCondition(comp *exprv1.Expr_Comprehension, schema Schema) (Condition, error) {
// Determine the comprehension kind by examining the loop initialization and step
kind, err := detectComprehensionKind(comp)
if err != nil {
return nil, err
}
// Get the field being iterated over
iterRangeIdent := comp.IterRange.GetIdentExpr()
if iterRangeIdent == nil {
return nil, errors.New("comprehension range must be a field identifier")
}
fieldName := iterRangeIdent.GetName()
// Validate the field
field, ok := schema.Field(fieldName)
if !ok {
return nil, errors.Errorf("unknown field %q in comprehension", fieldName)
}
if field.Kind != FieldKindJSONList {
return nil, errors.Errorf("field %q does not support comprehension (must be a list)", fieldName)
}
// Extract the predicate from the loop step
predicate, err := extractPredicate(comp, schema)
if err != nil {
return nil, err
}
View on GitHub (pinned to 14d757ce1f)
Solutions
- Iterate a schema list field directly: tag.exists(t, t.startsWith("w"))
- Replace inline-list tests with the in operator: x in ["a","b"]
- Check the schema (FieldKind JSONList) for which fields comprehensions accept
Example fix
// before
["work","urgent"].exists(t, t.startsWith("w"))
// after
tag.exists(t, t.startsWith("w")) Defensive patterns
Strategy: validation
Validate before calling
// TS: only allow comprehension ranges that are known list fields
const LIST_FIELDS = ['tag' /* per schema */];
if (!LIST_FIELDS.includes(rangeField)) {
throw new Error(`comprehension must iterate a list field (${LIST_FIELDS.join(', ')})`);
} Type guard
const isListField = (f: string): boolean => LIST_FIELDS.includes(f);
Prevention
- Iterate only declared JSON-list fields (e.g. tag) in exists/all
- Use the in operator for membership tests over inline lists
- Keep a schema allow-list of comprehension-capable fields in client code
When it happens
Trigger: Filters like [1,2,3].exists(x, x > 1) or size(tag).exists(t, t == "work") — the comprehension iterates over something other than a plain field name.
Common situations: Porting generic CEL list idioms that iterate over inline lists or computed ranges; the memos filter dialect only supports iterating a declared JSON-list field such as tag.
Related errors
- size() expects one argument
- set operations require a list literal as the second argument
- comprehension accumulator must be initialized with a constan
- unsupported comprehension type (supported: exists, all, exis
- comprehension loop step must be a call expression
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/572b4a23affc82ac.
Report an issue: GitHub.