usememos/memos · error

division by zero

Error message

division by zero

What it means

During constant folding of division, the right operand evaluated to zero. Because the fold happens at compile time, the filter is rejected before execution; there is no SQL NULL/Infinity escape hatch for integer division by zero in this DSL.

Source

Thrown at internal/filter/parser.go:573

			return 0, false, nil
		}
		right, ok, err := evaluateNumeric(call.Args[1], now)
		if err != nil {
			return 0, false, err
		}
		if !ok {
			return 0, false, nil
		}
		switch call.Function {
		case "_+_":
			return left + right, true, nil
		case "_-_":
			return left - right, true, nil
		case "_*_":
			return left * right, true, nil
		case "_/_":
			if right == 0 {
				return 0, false, errors.New("division by zero")
			}
			return left / right, true, nil
		case "_%_":
			if right == 0 {
				return 0, false, errors.New("modulo by zero")
			}
			return left % right, true, nil
		default:
			return 0, false, errors.Errorf("unsupported arithmetic operator %q", call.Function)
		}
	default:
		return 0, false, nil
	}
}

// evaluateTimestamp folds timestamp("RFC3339") and timestamp(<epoch int>) into
// Unix epoch seconds.
func evaluateTimestamp(call *exprv1.Expr_Call) (int64, bool, error) {

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Remove or fix the division so the constant divisor is non-zero
  2. Guard divisor-producing config values in the calling code before embedding them
  3. Use multiplication instead when the divisor is meant to scale

Example fix

// before
created_ts > timestamp("2024-01-01T00:00:00Z") / 0

// after
created_ts > timestamp("2024-01-01T00:00:00Z")
Defensive patterns

Strategy: validation

Validate before calling

// TS: reject zero divisors in generated filters
const divisor = Number(cfg.divisor);
if (!Number.isFinite(divisor) || divisor === 0) {
  throw new Error('divisor must be a non-zero number');
}
const filter = `created_ts > ${ts} / ${divisor}`;

Type guard

const isNonZeroNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v !== 0;

Try / catch

try { compile(filter); } catch (e) { if (String(e).includes('division by zero')) { filter = filter.replace(/\/\s*0(?![.0-9])/g, ''); compile(filter); } else throw e; }

Prevention

When it happens

Trigger: Filters like created_ts > timestamp("2024-01-01T00:00:00Z") / 0 or visibility == 10 / 0 where both sides fold to constants and the divisor is 0. Also duration("0h") used as a divisor: now - duration("0h") style expressions where a zero folds into '_/_'.

Common situations: Generated filters that compute a divisor from configuration (page size, divisor constant) that can be zero; copy-pasted arithmetic where the denominator was meant to be a field, not a literal.

Related errors


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