n8n-io/n8n · error · ExpressionExtensionError

isEven() is only callable on integers

Error message

isEven() is only callable on integers

What it means

isEven() in the number extensions requires an integer receiver; the value it was called on is fractional (e.g. from float division). Strict validation inside the extension throws immediately rather than rounding silently.

Solutions

  1. Round or truncate first, e.g. Math.round(value).isEven()
  2. Fix the upstream computation so it yields an integer (use integer-friendly operations)
  3. Use a modulo check in a Code node if fractional handling must be explicit

Example fix

// before
{{ $json.ratio.isEven() }}
// after
{{ $json.ratio.floor().isEven() }}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Number.isInteger($json.n)) {
  throw new Error('isEven(): value must be an integer, got ' + $json.n);
}
return $json;

Type guard

const isInteger = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v);

Prevention

When it happens

Trigger: `.isEven()` on `3.5`, on `NaN`, on a value that arrived as a float after division, or on a non-number that slipped past the type dispatch.

Common situations: Division or average result that is fractional; a parsed float where an integer was expected; currency amount with decimals.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/ffcd7c8626751b67. Report an issue: GitHub.

Appendix: source

Thrown at packages/@n8n/expression-runtime/src/extensions/number-extensions.ts:25

// The original uses Intl.NumberFormat which is a Web API unavailable inside the
// V8 isolate. toLocaleString is an ECMAScript built-in available in all V8
// contexts and produces the same output.
function format(value: number, extraArgs: unknown[]): string {
	const [locales = 'en-US', config = {}] = extraArgs as [
		string | string[],
		Intl.NumberFormatOptions,
	];

	try {
		return value.toLocaleString(locales as string, config);
	} catch {
		return String(value);
	}
}

function isEven(value: number) {
	if (!Number.isInteger(value)) {
		throw new ExpressionExtensionError('isEven() is only callable on integers');
	}
	return value % 2 === 0;
}

function isOdd(value: number) {
	if (!Number.isInteger(value)) {
		throw new ExpressionExtensionError('isOdd() is only callable on integers');
	}
	return Math.abs(value) % 2 === 1;
}

function floor(value: number) {
	return Math.floor(value);
}

function ceil(value: number) {
	return Math.ceil(value);
}

View on GitHub (pinned to 5ac6606e81)