usememos/memos · error
equality predicate expects exactly two arguments
Error message
equality predicate expects exactly two arguments
What it means
buildEqualsPredicate translates t == "value" inside a comprehension. It requires the == call to have exactly two arguments so it can determine which side is the iteration variable and which side is the constant. Any other arity is rejected.
Solutions
- Use the textual == operator inside the macro: tag.exists(t, t == "value")
- When building ASTs, always give _==_ exactly two args
Defensive patterns
Strategy: try-catch
Try / catch
if err := r.Render(cond); err != nil {
if strings.Contains(err.Error(), "exactly two arguments") {
return errors.New("== inside a macro must compare two operands")
}
return err
} Prevention
- Use textual == inside macros
- Keep binary operator AST nodes two-arg
When it happens
Trigger: A programmatically built _==_ call with 0, 1, or 3+ args; textual CEL cannot produce this because == is a binary operator. So in practice this guards against malformed ASTs only.
Common situations: Custom macro/AST pipelines; tests constructing Expr_Call nodes directly with wrong arg counts.
Related errors
- comprehension accumulator must be initialized with a…
- comprehension loop step must be a call expression
- comprehension loop step must have two arguments
- comprehension predicate must be a function call
- contains argument must be a string
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/2b7be42e998981cc.
Report an issue: GitHub.
Appendix: source
Thrown at internal/filter/parser.go:921
// Handle different predicate functions
switch predicateCall.Function {
case "_==_":
return buildEqualsPredicate(predicateCall, comp.IterVar)
case "startsWith":
return buildStartsWithPredicate(predicateCall, comp.IterVar)
case "endsWith":
return buildEndsWithPredicate(predicateCall, comp.IterVar)
case "contains":
return buildContainsPredicate(predicateCall, comp.IterVar)
default:
return nil, errors.Errorf(`unsupported predicate function %q in comprehension (supported: ==, startsWith, endsWith, contains)`, predicateCall.Function)
}
}
// buildEqualsPredicate extracts the value from t == "value".
func buildEqualsPredicate(call *exprv1.Expr_Call, iterVar string) (PredicateExpr, error) {
if len(call.Args) != 2 {
return nil, errors.New("equality predicate expects exactly two arguments")
}
var constExpr *exprv1.Expr
switch {
case isIterVarExpr(call.Args[0], iterVar):
constExpr = call.Args[1]
case isIterVarExpr(call.Args[1], iterVar):
constExpr = call.Args[0]
default:
return nil, errors.Errorf("equality predicate must compare against the iteration variable %q", iterVar)
}
value, err := getConstValue(constExpr)
if err != nil {
return nil, errors.Wrap(err, "equality argument must be a constant string")
}
valueStr, ok := value.(string)View on GitHub (pinned to 14d757ce1f)