usememos/memos · error
comprehension accumulator must be initialized with a constan
Error message
comprehension accumulator must be initialized with a constant
What it means
This error comes from the CEL-to-SQL filter parser in internal/filter. When the parser meets a comprehension (the AST form a CEL macro like exists()/all()/exists_one() expands to), it identifies which macro it is by inspecting the accumulator initialization expression. detectComprehensionKind requires AccuInit to be a constant literal (false for exists, true for all, int 0 for exists_one). If the accumulator is initialized with anything that is not a constant expression, the parser cannot classify the comprehension and refuses it.
Source
Thrown at internal/filter/parser.go:847
if err != nil {
return nil, err
}
return &ListComprehensionCondition{
Kind: kind,
Field: fieldName,
IterVar: comp.IterVar,
Predicate: predicate,
}, nil
}
// detectComprehensionKind determines if this is an exists() macro.
// Only exists() is currently supported.
func detectComprehensionKind(comp *exprv1.Expr_Comprehension) (ComprehensionKind, error) {
// Check the accumulator initialization
accuInit := comp.AccuInit.GetConstExpr()
if accuInit == nil {
return "", errors.New("comprehension accumulator must be initialized with a constant")
}
// exists() starts with false and uses OR (||) in loop step
if !accuInit.GetBoolValue() {
if step := comp.LoopStep.GetCallExpr(); step != nil && step.Function == "_||_" {
return ComprehensionExists, nil
}
}
// 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.View on GitHub (pinned to 14d757ce1f)
Solutions
- Rewrite the filter to use the plain macro form, e.g. tag.exists(t, t == "work") with literal false/true accumulator semantics
- If you build ASTs programmatically, set the comprehension's AccuInit to a constant expression (bool false for exists, true for all, int64 0 for exists_one)
- Check the cel-go version used by the project has not changed macro expansion; pin/align with the version in go.mod
Example fix
// before (invalid accumulation shape / non-macro comprehension) filter.Parse(`tag.exists(t, t == someVar)`) // after filter.Parse(`tag.exists(t, t == "work")`)
Defensive patterns
Strategy: validation
Validate before calling
// Reject non-standard comprehensions before rendering: only use textual macros
import "regexp"
var comprehensionLike = regexp.MustCompile(`\.\s*(map|filter|sum|exists|all|exists_one)\s*\(`)
func precheckFilter(expr string) error {
for _, m := range comprehensionLike.FindAllStringSubmatch(expr, -1) {
switch m[1] {
case "exists", "all", "exists_one":
default:
return fmt.Errorf("unsupported macro %q", m[1])
}
}
return nil
} Try / catch
err := renderer.Render(cond)
if err != nil {
if strings.Contains(err.Error(), "comprehension accumulator") {
// surface as user-facing validation message
return fmt.Errorf("invalid filter: use exists()/all()/exists_one() macros: %w", err)
}
return err
} Prevention
- Always author filters as textual CEL macros, never build comprehension ASTs by hand
- Pin the cel-go version to keep macro expansion shapes stable
- Validate user filters in the UI before submitting them to the API
When it happens
Trigger: A CEL filter expression whose macro accumulator is not a plain constant, e.g. a user-supplied or programmatically built expression like tag.exists(t, t == variableName) where the macro was hand-constructed instead of using the standard exists() syntax, or a modified/custom CEL environment that rewrites the accumulator init to a non-constant expr. Passing an already-macro-expanded AST with AccuInit as a call or ident instead of a const produces this on Parse of the filter.
Common situations: Building CEL expressions programmatically with cel.NewAst / custom macros rather than parsing the textual form; upgrading cel-go versions that change macro expansion shape; users pasting exotic filter strings (lambda-style syntax) into the memos filter UI that the CEL parser turns into non-standard comprehensions.
Related errors
- unsupported comprehension type (supported: exists, all, exis
- 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/c824933502b7a2b4.
Report an issue: GitHub.