usememos/memos · error

logical AND expects two arguments

Error message

logical AND expects two arguments

What it means

Returned by buildCallCondition for the "_&&_" (logical AND) function when the AST call does not have exactly 2 arguments. Standard CEL always produces binary &&, so hitting this means the AST was built unusually (macro expansion edge cases or programmatic AST construction) or an internal invariant broke.

Source

Thrown at internal/filter/parser.go:52

		if !ok {
			return nil, errors.Errorf("unknown identifier %q", name)
		}
		if field.Type != FieldTypeBool {
			return nil, errors.Errorf("identifier %q is not boolean", name)
		}
		return &FieldPredicateCondition{Field: name}, nil
	case *exprv1.Expr_ComprehensionExpr:
		return buildComprehensionCondition(v.ComprehensionExpr, pc.schema)
	default:
		return nil, errors.New("unsupported top-level expression")
	}
}

func buildCallCondition(call *exprv1.Expr_Call, pc parseContext) (Condition, error) {
	switch call.Function {
	case "_&&_":
		if len(call.Args) != 2 {
			return nil, errors.New("logical AND expects two arguments")
		}
		left, err := buildCondition(call.Args[0], pc)
		if err != nil {
			return nil, err
		}
		right, err := buildCondition(call.Args[1], pc)
		if err != nil {
			return nil, err
		}
		return &LogicalCondition{
			Operator: LogicalAnd,
			Left:     left,
			Right:    right,
		}, nil
	case "_||_":
		if len(call.Args) != 2 {
			return nil, errors.New("logical OR expects two arguments")
		}

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Rewrite the && expression in plain binary form (a && b, parenthesizing chains explicitly).
  2. If generating ASTs programmatically, ensure logic operators are emitted with exactly two args.
  3. Report as an engine bug if a plain, hand-written filter triggers it.

Example fix

# before (odd grouping / generated)
(a && b && c)

# after (explicit binary chain)
((a && b) && c)
Defensive patterns

Strategy: validation

Validate before calling

// Go — parenthesize generated chains so each _&&_ is binary
// instead of: buildAnd(a, b, c)
// emit: ((a && b) && c)
func andPair(l, r string) string { return fmt.Sprintf("(%s && %s)", l, r) }

Try / catch

if err != nil && strings.Contains(err.Error(), "logical AND expects two arguments") {
  return errors.Wrap(err, "internal filter AST inconsistency; report with the filter text")
}

Prevention

When it happens

Trigger: A filter using && where the parsed Expr_Call for _&&_ carries arg count != 2 — practically rare via user input; more likely from custom ASTs or a CEL macro that desugars into _&&_ with unexpected arity.

Common situations: Almost never triggered by hand-written filters; can appear when generating filters programmatically or with nonstandard CEL parse options that rewrite logic ops.

Related errors


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