n8n-io/n8n · error · ExpressionExtensionError
removeFieldsContaining(): expected non-empty string arg
Error message
removeFieldsContaining(): expected non-empty string arg
What it means
The object extension `removeFieldsContaining(match)` deletes object fields whose STRING value contains `match`. It throws when `match` is not a string or is the empty string, since an empty match would match (and delete) every string field — a destructive footgun the guard explicitly prevents.
Source
Thrown at packages/@n8n/expression-runtime/src/extensions/object-extensions.ts:39
const [name] = extraArgs;
return name in value;
}
function removeField(value: object, extraArgs: string[]): object {
const [name] = extraArgs;
if (name in value) {
const newObject = { ...value };
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
delete (newObject as any)[name];
return newObject;
}
return value;
}
function removeFieldsContaining(value: object, extraArgs: string[]): object {
const [match] = extraArgs;
if (typeof match !== 'string' || match === '') {
throw new ExpressionExtensionError('removeFieldsContaining(): expected non-empty string arg');
}
const newObject = { ...value };
for (const [key, val] of Object.entries(value)) {
if (typeof val === 'string' && val.includes(match)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
delete (newObject as any)[key];
}
}
return newObject;
}
function keepFieldsContaining(value: object, extraArgs: string[]): object {
const [match] = extraArgs;
if (typeof match !== 'string' || match === '') {
throw new ExpressionExtensionError(
'argument of keepFieldsContaining must be a non-empty string',
);
}View on GitHub (pinned to 5ac6606e81)
Solutions
- Pass a non-empty string literal or expression: `.removeFieldsContaining('tmp_')`.
- Guard the match value in a Code node and only call the extension when it is a non-empty string.
- If you genuinely want to remove all string fields, iterate and delete them explicitly in a Code node.
Example fix
// before
{{ $json.row.removeFieldsContaining($json.maybeEmpty) }}
// after
{{ $json.row.removeFieldsContaining($json.maybeEmpty || 'UNDEFINED') }} Defensive patterns
Strategy: validation
Validate before calling
const match = $json.match;
if (typeof match !== 'string' || match === '') {
throw new Error('removeFieldsContaining(): match must be a non-empty string');
}
return $json; Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Prevention
- Pass a non-empty string match.
- Guard dynamic match values in a Code node before the expression.
- Coerce numerics with `String(...)` if a numeric substring match is intended.
When it happens
Trigger: `.removeFieldsContaining('')` or `.removeFieldsContaining(123)` or `.removeFieldsContaining(undefined)`.
Common situations: A dynamic match value pulled from upstream that happens to be empty; a numeric match where a string was intended; field rename left `match` undefined.
Related errors
- argument of keepFieldsContaining must be a non-empty string
- intersection(): expected array arg, e.g. .intersection([1, 2
- keys and values must be arrays
- Unknown algorithm ${algorithm}. Available algorithms are: ${
- Unsupported unit '${String(errorUnit)}'. Supported: ${durati
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/8b9a6a694f2effb7.
Report an issue: GitHub.