dgraph-io/dgraph · error

Division by zero

Error message

Division by zero

What it means

The math parser detects division (or modulo) by a constant zero operand and rejects the query before evaluation. In the unary branch this fires when a '/' or '%' operator sits on the operator stack above a unary op whose operand constant is zero. DQL math is evaluated per-node and constant zero divisors are statically detected.

Source

Thrown at dql/math.go:117

	return false
}

func evalMathStack(opStack, valueStack *mathTreeStack) error {
	topOp, err := opStack.pop()
	if err != nil {
		return errors.Errorf("Invalid Math expression")
	}
	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) {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Guard the divisor: use cond(a != 0, a / b, 0) style ternary, or filter out zero-divisor values first.
  2. Replace literal 0 divisors with a real value or sentinel like 1.
  3. Use val() variables computed with max(divisor, 1) style logic (math(max(d,1)) as safe_d) before dividing.
  4. Reorder computation so the divisor is never the constant zero.

Example fix

// before
d as math(count / 0)
// after
d as math(cond(divisor == 0, 0, count / divisor))
Defensive patterns

Strategy: validation

Validate before calling

// Reject constant-zero divisors before sending
function hasZeroDivisor(expr) {
  return /\/\s*0(\.0+)?\b/.test(expr) || /%\s*0(\.0+)?\b/.test(expr);
}
if (hasZeroDivisor('a / 0')) throw new Error('Constant zero divisor in math expression');

Try / catch

try {
  return await dgraph.query(query);
} catch (err) {
  if (/Division by zero\.?$/.test(String(err).trim())) {
    throw new Error('Replace zero divisors with cond-guarded division: cond(d == 0, 0, a / d)');
  }
  throw err;
}

Prevention

When it happens

Trigger: Expressions like math(a / 0) or math(a % 0), or unary results known to be zero feeding a division, e.g. math(a / floor(0.5)) since floor(0.5) == 0.

Common situations: Hardcoded 0 divisor left in query from templating; computing a divisor with floor/ceil that lands on 0 for some values; math(a / since(u)) where since can be 0 for fresh nodes.

Related errors


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