{"record":{"id":"5d1bff2045d49047","repo":"n8n-io/n8n","slug":"argument-of-keepfieldscontaining-must-be-a-non-emp","errorCode":null,"errorMessage":"argument of keepFieldsContaining must be a non-empty string","messagePattern":"argument of keepFieldsContaining must be a non-empty string","errorType":"exception","errorClass":"ExpressionExtensionError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/expression-runtime/src/extensions/object-extensions.ts","lineNumber":54,"sourceCode":"function removeFieldsContaining(value: object, extraArgs: string[]): object {\n\tconst [match] = extraArgs;\n\tif (typeof match !== 'string' || match === '') {\n\t\tthrow new ExpressionExtensionError('removeFieldsContaining(): expected non-empty string arg');\n\t}\n\tconst newObject = { ...value };\n\tfor (const [key, val] of Object.entries(value)) {\n\t\tif (typeof val === 'string' && val.includes(match)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tdelete (newObject as any)[key];\n\t\t}\n\t}\n\treturn newObject;\n}\n\nfunction keepFieldsContaining(value: object, extraArgs: string[]): object {\n\tconst [match] = extraArgs;\n\tif (typeof match !== 'string' || match === '') {\n\t\tthrow new ExpressionExtensionError(\n\t\t\t'argument of keepFieldsContaining must be a non-empty string',\n\t\t);\n\t}\n\tconst newObject = { ...value };\n\tfor (const [key, val] of Object.entries(value)) {\n\t\tif (typeof val !== 'string' || (typeof val === 'string' && !val.includes(match))) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tdelete (newObject as any)[key];\n\t\t}\n\t}\n\treturn newObject;\n}\n\nexport function compact(value: object): object {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst newObj: any = {};\n\tfor (const [key, val] of Object.entries(value)) {\n\t\tif (val !== null && val !== undefined && val !== 'nil' && val !== '') {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/expression-runtime/src/extensions/object-extensions.ts#L36-L72","documentation":"Twin of 333: the object extension `keepFieldsContaining(match)` retains only fields whose string value contains `match`, deleting the rest. The same guard rejects a non-string or empty `match` — an empty match would (correctly but uselessly) keep everything, and a non-string match cannot substring-test.","triggerScenarios":"`.keepFieldsContaining('')` or `.keepFieldsContaining(null)` or `.keepFieldsContaining(42)`.","commonSituations":"Dynamic match value that is empty or the wrong type; field rename leaving `match` undefined; numeric ID used as a substring match.","solutions":["Pass a non-empty string match: `.keepFieldsContaining('email')`.","Pre-validate the match value in a Code node.","Coerce numerics with `.toString()` if a numeric substring match is intended."],"exampleFix":"// before\n{{ $json.row.keepFieldsContaining($json.q) }}\n// after\n{{ $json.row.keepFieldsContaining(String($json.q || '')) || $json.row }}","handlingStrategy":"validation","validationCode":"const match = $json.match;\nif (typeof match !== 'string' || match === '') {\n  throw new Error('keepFieldsContaining(): match must be a non-empty string');\n}\nreturn $json;","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;","tryCatchPattern":null,"preventionTips":["Pass a non-empty string match.","Pre-validate dynamic match values upstream.","Coerce numerics with `String(...)` when needed."],"tags":["expression","object","string","validation","argument-shape"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}