{"record":{"id":"56620254f9f70895","repo":"Zie619/n8n-workflows","slug":"pii-column-names-are-missing-in-the-input-data-566202","errorCode":null,"errorMessage":"PII column names are missing in the input data.","messagePattern":"PII column names are missing in the input data\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"workflows/Splitout/1637_Splitout_Code_Automation_Triggered.json","lineNumber":226,"sourceCode":"      \"parameters\": {\n        \"options\": {\n          \"destinationFieldName\": \"data\"\n        },\n        \"fieldToSplitOut\": \"message.content.content\"\n      },\n      \"typeVersion\": 1,\n      \"notes\": \"This splitOut node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"4207dc71-5b0e-4780-9f23-00f5a7fc3862\",\n      \"name\": \"Remove PII columns\",\n      \"type\": \"n8n-nodes-base.code\",\n      \"position\": [\n        580,\n        260\n      ],\n      \"parameters\": {\n        \"jsCode\": \"// Input: All items from the previous node\\nconst input = $input.all();\\n\\n// Step 1: Extract the PII column names from the first item\\nconst firstItem = input[0];\\nif (!firstItem.json.data || !firstItem.json.data) {\\n throw new Error(\\\"PII column names are missing in the input data.\\\");\\n}\\nconst piiColumns = firstItem.json.data.split(',').map(col => col.trim());\\n//console.log(\\\"PII Columns to Remove:\\\", piiColumns);\\n\\n// Step 2: Remove the first two items and process the remaining rows\\nlet rows = input.slice(2).map(item => item.json); // Exclude the first item\\n//console.log(\\\"Rows to convert (before skipping last):\\\", rows);\\n\\n\\n// Ensure there are rows to process\\nif (rows.length === 0) {\\n throw new Error(\\\"No rows to convert to CSV.\\\");\\n}\\n\\n// Step 3: Remove PII columns from each row\\nconst sanitizedRows = rows.map(row => {\\n const sanitizedRow = { ...row }; // Copy the row\\n piiColumns.forEach(column => delete sanitizedRow[column]); // Remove PII columns\\n return sanitizedRow;\\n});\\n//console.log(\\\"Sanitized Rows:\\\", sanitizedRows);\\n\\n// Step 4: Extract headers from sanitized rows\\nconst headers = Object.keys(sanitizedRows[0]); // Extract updated headers\\n//console.log(\\\"CSV Headers:\\\", headers);\\n\\n// Step 5: Convert rows to CSV format\\nconst csvRows = [\\n headers.join(','), // Add header row\\n ...sanitizedRows.map(row => \\n headers.map(header => String(row[header] || '').replace(/,/g, '')).join(',') // Match headers with rows\\n )\\n];\\n\\n// Join all rows with a newline character\\nconst csvContent = csvRows.join('\\\\n');\\n//console.log(\\\"CSV Content:\\\", csvContent);\\n\\nconst originalFileName = input[1].json.originalFilename;\\n\\n// Step 7: Generate a new filename\\nconst fileExtension = originalFileName.split('.').pop();\\nconst baseName = originalFileName.replace(`.${fileExtension}`, '');\\nconst newFileName = `${baseName}_PII_removed.${fileExtension}`;\\n//console.log(\\\"New Filename:\\\", newFileName);\\n\\n// Step 8: Return the CSV content and filename as JSON\\nreturn [\\n {\\n json: {\\n fileName: newFileName, // New file name\\n content: csvContent // CSV content as plain text\\n }\\n }\\n];\\n\"\n      },\n      \"typeVersion\": 2,\n      \"notes\": \"This code node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"e9f25ee7-cd00-4496-9062-5d57cab5788d\",\n      \"name\": \"Sticky Note\",\n      \"type\": \"n8n-nodes-base.stickyNote\",\n      \"position\": [\n        -300,\n        -220\n      ],\n      \"parameters\": {\n        \"height\": 260,\n        \"content\": \"## Remove PII from CSV Files\\nThis workflow monitors a Google Drive folder for new CSV files, identifies and removes PII columns using OpenAI, and uploads the sanitized file back to the drive. It requires Google Drive and OpenAI integrations with API access enabled.\"\n      },\n      \"typeVersion\": 1,\n      \"notes\": \"This stickyNote node performs automated tasks as part of the workflow.\"","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/Zie619/n8n-workflows/blob/94007c1445d9258a7da116646b79473e7c7c3282/workflows/Splitout/1637_Splitout_Code_Automation_Triggered.json#L208-L244","documentation":"Thrown by the 'Remove PII columns' Code node when the first input item lacks a json.data string. The node expects a specific multi-item layout: input[0].json.data holds a comma-separated list of PII column names, input[1].json.originalFilename holds the file name, and input[2+] are the data rows. If item 0 has no .data property, the PII column list cannot be built and the node aborts.","triggerScenarios":"The upstream node (spreadsheet/file parser) emitted items in a different order or shape, json.data is an object/array instead of the expected comma-separated string, the file was empty so only one item arrived, or a prior node was changed to pass rows starting at index 0.","commonSituations":"Reordering items between nodes, switching the file parser (Read PDF/CSV vs Google Sheets) which changes item structure, or a config change where the PII-column header row is no longer the first item. Note the guard itself is buggy: it checks !firstItem.json.data twice instead of also validating input[1].originalFilename, so a missing filename fails later with an unrelated TypeError.","solutions":["Pin and inspect $input.all() upstream: verify item 0 contains a comma-separated column string in json.data and item 1 contains originalFilename.","Fix the upstream node so the PII header item and filename item are emitted in positions 0 and 1 (e.g., adjust the Set/splitOut ordering).","Harden the guard: also check typeof firstItem.json.data === 'string' and validate input[1]?.json?.originalFilename before use.","If the payload shape has permanently changed (e.g., columns now arrive as an array), parse accordingly: Array.isArray(d) ? d : d.split(',')."],"exampleFix":"// before\nif (!firstItem.json.data || !firstItem.json.data) {\n throw new Error(\"PII column names are missing in the input data.\");\n}\nconst piiColumns = firstItem.json.data.split(',').map(col => col.trim());\nconst originalFileName = input[1].json.originalFilename;\n\n// after - validate the whole contract up front\nconst headerItem = input[0]?.json;\nconst fileItem = input[1]?.json;\nif (typeof headerItem?.data !== 'string' || headerItem.data.trim() === '') {\n  throw new Error(`PII column names are missing in the input data (item 0 keys: ${Object.keys(headerItem || {}).join(',')})`);\n}\nif (typeof fileItem?.originalFilename !== 'string' || !fileItem.originalFilename) {\n  throw new Error('originalFilename is missing on input item 1.');\n}\nconst piiColumns = headerItem.data.split(',').map(col => col.trim());\nconst originalFileName = fileItem.originalFilename;","handlingStrategy":"validation","validationCode":"// Contract check before any processing:\nconst header = input[0]?.json;\nconst fileMeta = input[1]?.json;\nconst rows = input.slice(2);\nconst ok =\n  typeof header?.data === 'string' && header.data.trim() !== '' &&\n  typeof fileMeta?.originalFilename === 'string' && fileMeta.originalFilename !== '' &&\n  rows.length > 0;\nif (!ok) {\n  throw new Error(`Unexpected input layout. Item counts: ${input.length}; item0 keys: ${Object.keys(header || {}).join(',')}`);\n}","typeGuard":"const isPiiLayout = (items) =>\n  items.length >= 3 &&\n  typeof items[0]?.json?.data === 'string' &&\n  typeof items[1]?.json?.originalFilename === 'string' &&\n  typeof items[2]?.json === 'object';","tryCatchPattern":null,"preventionTips":["Validate the full multi-item contract (header item, filename item, rows) in one guard instead of checking the same field twice.","Pin a sample file run so the parser's item layout is locked in and visible.","When swapping the file-reader node, re-check item order and key names before re-enabling the workflow."],"tags":["n8n","code-node","validation","csv","pii","data-shape"],"backgroundTag":null,"analyzedSha":"94007c1445d9258a7da116646b79473e7c7c3282","analyzedAt":"2026-08-15T04:10:37.591Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}