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

  1. Pass a non-empty string literal or expression: `.removeFieldsContaining('tmp_')`.
  2. Guard the match value in a Code node and only call the extension when it is a non-empty string.
  3. 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

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


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