usememos/memos · error
unsupported comprehension type (supported: exists, all, exis
Error message
unsupported comprehension type (supported: exists, all, exists_one)
What it means
detectComprehensionKind recognized a comprehension but could not match it to any supported macro. The parser only supports exists() (accu=false + ||), all() (accu=true + &&), and exists_one() (accu=int 0 + ternary). Any other comprehension shape — map(), filter(), list macros, sum(), etc. — falls through to this error.
Source
Thrown at internal/filter/parser.go:872
}
}
// all() starts with true and uses AND (&&) in the loop step.
if accuInit.GetBoolValue() {
if step := comp.LoopStep.GetCallExpr(); step != nil && step.Function == "_&&_" {
return ComprehensionAll, nil
}
}
// exists_one() starts at int(0) and increments via a conditional (predicate ?
// accu + 1 : accu) in the loop step.
if _, isInt := accuInit.GetConstantKind().(*exprv1.Constant_Int64Value); isInt {
if step := comp.LoopStep.GetCallExpr(); step != nil && step.Function == "_?_:_" {
return ComprehensionExistsOne, nil
}
}
return "", errors.New("unsupported comprehension type (supported: exists, all, exists_one)")
}
// extractPredicate extracts the predicate expression from the comprehension loop step.
func extractPredicate(comp *exprv1.Expr_Comprehension, _ Schema) (PredicateExpr, error) {
// The loop step is: @result || predicate(t) for exists
// or: @result && predicate(t) for all
step := comp.LoopStep.GetCallExpr()
if step == nil {
return nil, errors.New("comprehension loop step must be a call expression")
}
// exists/all: accu || predicate / accu && predicate -> predicate is arg[1].
// exists_one: predicate ? accu + 1 : accu -> predicate is arg[0].
var predicateExpr *exprv1.Expr
if step.Function == "_?_:_" {
if len(step.Args) != 3 {
return nil, errors.New("exists_one loop step must have three arguments")
}View on GitHub (pinned to 14d757ce1f)
Solutions
- Restrict list predicates to exists(), all(), or exists_one(), e.g. tag.exists(t, t.startsWith("work"))
- Replace map()/filter() intent with the supported predicate functions ==, startsWith, endsWith, contains inside exists/all
Example fix
// before `tag.map(t, t.upperAscii()).exists(t, t == "WORK")` // after `tag.exists(t, t == "work")`
Defensive patterns
Strategy: validation
Validate before calling
var unsupportedMacros = regexp.MustCompile(`\.\s*(map|filter|sum|take|drop)\s*\(`)
func validateFilter(expr string) error {
if unsupportedMacros.MatchString(expr) {
return errors.New("only exists/all/exists_one macros are supported")
}
return nil
} Try / catch
if err := r.Render(cond); err != nil {
if strings.Contains(err.Error(), "unsupported comprehension type") {
return userErr("filter uses an unsupported list macro; use exists, all, or exists_one")
}
return err
} Prevention
- Document the supported macro whitelist (exists, all, exists_one) at the filter input UI
- Test filter strings against the parser in CI when shipping new filter examples
- Reject filters early at the API boundary instead of at SQL render time
When it happens
Trigger: CEL filter using an unsupported macro on a list field, e.g. tag.map(t, t.size()) , tag.filter(...), tag.sum(...) or exists_one written against a loop step the pattern matcher does not recognize (e.g. accu init is int but loop step is not _?_:_).
Common situations: Users familiar with full CEL try list transformations in the memo filter bar; API clients send filters copied from other CEL-based systems (Envoy, Firebase rules) that allow map/filter macros.
Related errors
- comprehension accumulator must be initialized with a constan
- comprehension loop step must be a call expression
- exists_one loop step must have three arguments
- comprehension loop step must have two arguments
- comprehension predicate must be a function call
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/0372fc004623b87f.
Report an issue: GitHub.