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.

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)

Solutions

  1. Use the textual == operator inside the macro: tag.exists(t, t == "value")
  2. 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

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


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