n8n-io/n8n · error · ExpressionExtensionError
union(): expected array arg, e.g. .union([1, 2, 3, 4])
Error message
union(): expected array arg, e.g. .union([1, 2, 3, 4])
What it means
Thrown as ExpressionExtensionError by the .union() array extension when its argument is not an array. union() concatenates the base array with another array and removes duplicates; a non-array argument cannot be iterated for the concatenation step, so it is rejected.
Source
Thrown at packages/@n8n/expression-runtime/src/extensions/array-extensions.ts:272
const listLength = value.length > others.length ? value.length : others.length;
let merged = {};
for (let i = 0; i < listLength; i++) {
if (value[i] !== undefined) {
if (typeof value[i] === 'object' && typeof others[i] === 'object') {
merged = Object.assign(
merged,
mergeObjects(value[i] as Record<string, unknown>, [others[i]]),
);
}
}
}
return merged;
}
function union(value: unknown[], extraArgs: unknown[][]): unknown[] {
const [others] = extraArgs;
if (!Array.isArray(others)) {
throw new ExpressionExtensionError('union(): expected array arg, e.g. .union([1, 2, 3, 4])');
}
const newArr: unknown[] = Array.from(value);
for (const v of others) {
if (newArr.findIndex((w) => isEqual(w, v)) === -1) {
newArr.push(v);
}
}
return unique(newArr, []);
}
function difference(value: unknown[], extraArgs: unknown[][]): unknown[] {
const [others] = extraArgs;
if (!Array.isArray(others)) {
throw new ExpressionExtensionError(
'difference(): expected array arg, e.g. .difference([1, 2, 3, 4])',
);
}
const newArr: unknown[] = [];View on GitHub (pinned to 5ac6606e81)
Solutions
- Pass an array: .union([1,2,3,4]).
- If the argument is dynamic, ensure it is an array before calling: Array.isArray(arg) ? .union(arg) : .union([arg]).
- Coerce single values into a one-element array when a union with a scalar is intended.
- Confirm the upstream expression yields an array.
Example fix
// before — scalar argument
{{ $json.tags.union($json.moreTags) }} // if moreTags is a string, throws
// after — ensure array argument
{{ $json.tags.union(Array.isArray($json.moreTags) ? $json.moreTags : [$json.moreTags]) }} Defensive patterns
Strategy: type-guard
Validate before calling
function unionSafe(arr, others) {
if (!Array.isArray(others)) throw new TypeError('union(): expected array arg');
return [...new Set([...arr, ...others])];
} Type guard
function isUnionArgValid(others) { return Array.isArray(others); } Try / catch
try {
result = arr.union(others);
} catch (e) {
if (e.name === 'ExpressionExtensionError' && /union.*array/i.test(e.message)) {
// ensure others is an array: arr.union(Array.isArray(others) ? others : [others])
}
} Prevention
- Always pass an array: .union([1,2,3,4]).
- Coerce scalars: .union(Array.isArray(x) ? x : [x]).
- Guard with Array.isArray(arg) before calling.
- Confirm upstream expressions that produce the argument yield an array.
When it happens
Trigger: Calling .union() with a non-array: .union(5), .union('abc'), .union({a:1}), or .union() where the harness passes undefined (undefined fails Array.isArray). The expected form is .union([1,2,3,4]).
Common situations: Passing a scalar or object instead of an array. A template variable resolving to a single value rather than a list. Forgetting the brackets around the argument.
Related errors
- arguments must be passed to pluck
- smartJoin(): expected two string args, e.g. .smartJoin("name
- chunk(): expected non-zero numeric arg, e.g. .chunk(5)
- renameKeys(): expected an even amount of args: from1, to1 [,
- merge(): expected object arg
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/3e8dbb8f0161ed0e.
Report an issue: GitHub.