dgraph-io/dgraph · error

Invalid Math expression. Expected 3 operands

Error message

Invalid Math expression. Expected 3 operands

What it means

Error returned by the DQL math parser (dql/math.go) when a math function that requires exactly 3 operands (e.g. logbase or pow-style ternary functions) is given a different number of arguments. Fix by passing exactly three operands to the math function.

Source

Thrown at dql/math.go:124

	}
	switch {
	case isUnary(topOp.Fn):
		// Since "not" is a unary operator, just pop one value.
		topVal, err := valueStack.pop()
		if err != nil {
			return errors.Errorf("Invalid math statement. Expected 1 operands")
		}
		if opStack.size() > 1 {
			peek := opStack.peek().Fn
			if (peek == "/" || peek == "%") && isZero(topOp.Fn, topVal.Const) {
				return errors.Errorf("Division by zero")
			}
		}
		topOp.Child = []*MathTree{topVal}

	case isTernary(topOp.Fn):
		if valueStack.size() < 3 {
			return errors.Errorf("Invalid Math expression. Expected 3 operands")
		}
		topVal1 := valueStack.popAssert()
		topVal2 := valueStack.popAssert()
		topVal3 := valueStack.popAssert()
		topOp.Child = []*MathTree{topVal3, topVal2, topVal1}

	default:
		if valueStack.size() < 2 {
			return errors.Errorf("Invalid Math expression. Expected 2 operands")
		}
		if isZero(topOp.Fn, valueStack.peek().Const) {
			return errors.Errorf("Division by zero.")
		}
		topVal1 := valueStack.popAssert()
		topVal2 := valueStack.popAssert()
		topOp.Child = []*MathTree{topVal2, topVal1}

	}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Provide all three arguments: math(cond(condition, valueIfTrue, valueIfFalse)).
  2. Wrap nested sub-expressions in parentheses so each cond gets its own operand group.
  3. Count commas: a cond at top level inside math must have exactly two commas.
  4. Break complex nested cond expressions into intermediate variables (v as cond(...)).

Example fix

// before
u as math(cond(a, b))
// after
u as math(cond(a, b, 0))
Defensive patterns

Strategy: validation

Validate before calling

// cond must have exactly two commas at its own paren level
function validateCond(expr) {
  const m = expr.match(/cond\s*\(([^()]*)\)/);
  if (!m) return true;
  const commas = (m[1].match(/,/g) || []).length;
  if (commas !== 2) throw new Error('cond needs exactly 3 arguments');
  return true;
}

Try / catch

try {
  return await dgraph.query(query);
} catch (err) {
  if (/Expected 3 operands/.test(String(err))) {
    throw new Error('cond() in math requires 3 arguments: cond(cond, ifTrue, ifFalse)');
  }
  throw err;
}

Prevention

When it happens

Trigger: math(cond(a,b)) with only two arguments, math(cond()) with none, or an unbalanced comma causing cond to consume fewer values, e.g. missing nested parentheses around a sub-expression.

Common situations: Typos when writing conditional logic in aggregation math blocks; refactoring that dropped an argument; nested cond calls with mismatched commas: math(cond(a, cond(b, c, d))) miscounted.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/84a71b85ede0845b. Report an issue: GitHub.