{"record":{"id":"ffcd7c8626751b67","repo":"n8n-io/n8n","slug":"iseven-is-only-callable-on-integers","errorCode":null,"errorMessage":"isEven() is only callable on integers","messagePattern":"isEven\\(\\) is only callable on integers","errorType":"exception","errorClass":"ExpressionExtensionError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/expression-runtime/src/extensions/number-extensions.ts","lineNumber":25,"sourceCode":"// The original uses Intl.NumberFormat which is a Web API unavailable inside the\n// V8 isolate. toLocaleString is an ECMAScript built-in available in all V8\n// contexts and produces the same output.\nfunction format(value: number, extraArgs: unknown[]): string {\n\tconst [locales = 'en-US', config = {}] = extraArgs as [\n\t\tstring | string[],\n\t\tIntl.NumberFormatOptions,\n\t];\n\n\ttry {\n\t\treturn value.toLocaleString(locales as string, config);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nfunction isEven(value: number) {\n\tif (!Number.isInteger(value)) {\n\t\tthrow new ExpressionExtensionError('isEven() is only callable on integers');\n\t}\n\treturn value % 2 === 0;\n}\n\nfunction isOdd(value: number) {\n\tif (!Number.isInteger(value)) {\n\t\tthrow new ExpressionExtensionError('isOdd() is only callable on integers');\n\t}\n\treturn Math.abs(value) % 2 === 1;\n}\n\nfunction floor(value: number) {\n\treturn Math.floor(value);\n}\n\nfunction ceil(value: number) {\n\treturn Math.ceil(value);\n}","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/expression-runtime/src/extensions/number-extensions.ts#L7-L43","documentation":"`isEven(value)` requires `Number.isInteger(value)` to be true. Non-integer numbers (3.5, NaN, Infinity) and non-number values throw before the modulo is computed.","triggerScenarios":"`.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.","commonSituations":"Division or average result that is fractional; a parsed float where an integer was expected; currency amount with decimals.","solutions":["Round first: `.floor().isEven()` or `.toInt().isEven()`.","Validate the value is integral (`Number.isInteger(x)`) in a Code node before relying on the expression.","If fractional parity is meaningless for your domain, filter those rows out upstream."],"exampleFix":"// before\n{{ $json.ratio.isEven() }}\n// after\n{{ $json.ratio.floor().isEven() }}","handlingStrategy":"type-guard","validationCode":"if (!Number.isInteger($json.n)) {\n  throw new Error('isEven(): value must be an integer, got ' + $json.n);\n}\nreturn $json;","typeGuard":"const isInteger = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v);","tryCatchPattern":null,"preventionTips":["Round before parity checks: `.floor().isEven()`.","Filter fractional rows upstream when parity is meaningless for them.","Confirm upstream output is integral, not a float string."],"tags":["expression","number","integer","type-mismatch"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}