n8n-io/n8n · error · ExpressionExtensionError

keys and values not of equal length

Error message

keys and values not of equal length

What it means

The zip() expression extension received keys and values arrays of different lengths. It is a pair-wise zipping helper, so element counts must match exactly; the throw is a pure argument validation inside the expression runtime, before any object construction.

Solutions

  1. Make both arrays the same length before zipping (trim or pad deliberately)
  2. Check the upstream expression producing one of the arrays — an off-by-one or filter mismatch is the usual cause
  3. If unequal pairs are expected, handle them explicitly rather than via zip()

Example fix

// before
{{ zip(['a','b','c'], [1,2]) }}
// after
{{ zip(['a','b','c'], [1,2,null]) }}
Defensive patterns

Strategy: validation

Validate before calling

const { keys, values } = $json;
if (keys.length !== values.length) {
  throw new Error(`zip(): length mismatch (${keys.length} vs ${values.length})`);
}
return $json;

Type guard

const sameLength = (a: unknown[], b: unknown[]): boolean => a.length === b.length;

Prevention

When it happens

Trigger: A header array with 5 entries zipped against a row array with 4; mismatched parallel lists from upstream.

Common situations: Ragged source data (CSV rows with fewer columns than the header); one source pruned entries the other kept.

Related errors


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

Appendix: source

Thrown at packages/@n8n/expression-runtime/src/extensions/function-extensions.ts:28

	let curr = start;
	for (let i = 0; i < size; i++) {
		if (start < end) {
			arr[i] = curr++;
		} else {
			arr[i] = curr--;
		}
	}

	return arr;
};

const zip = (keys: unknown[], values: unknown[]): unknown => {
	if (!Array.isArray(keys) || !Array.isArray(values)) {
		throw new ExpressionExtensionError('keys and values must be arrays');
	}
	if (keys.length !== values.length) {
		throw new ExpressionExtensionError('keys and values not of equal length');
	}
	const result: Record<string, unknown> = {};
	for (let i = 0; i < keys.length; i++) {
		result[keys[i] as string] = values[i];
	}
	return result;
};

const average = (...args: number[]) => {
	return aAverage(args);
};

const not = (value: unknown): boolean => {
	return !value;
};

function ifEmpty<T, V>(value: V, defaultValue: T) {
	if (arguments.length !== 2) {

View on GitHub (pinned to 5ac6606e81)