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

  1. Rewrite the filter to use the plain macro form, e.g. tag.exists(t, t == "work") with literal false/true accumulator semantics
  2. 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)
  3. 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

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


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/c824933502b7a2b4. Report an issue: GitHub.