{"record":{"id":"358c9d41e6aa4877","repo":"Zie619/n8n-workflows","slug":"the-video-id-parameter-is-empty-358c9d","errorCode":null,"errorMessage":"The video ID parameter is empty.","messagePattern":"The video ID parameter is empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"workflows/Telegram/1982_Telegram_Splitout_Automation_Scheduled.json","lineNumber":110,"sourceCode":"              \"type\": \"array\",\n              \"value\": \"={{ $json[\\\"YouTube Channel Ids\\\"].length > 0  ? $json[\\\"YouTube Channel Ids\\\"] : $json[\\\"Default YouTube Channel Ids\\\"] }}\"\n            }\n          ]\n        }\n      },\n      \"typeVersion\": 3.4,\n      \"notes\": \"This set node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"7c8b43fb-52c9-4a3e-b5ff-2c21fe8fb183\",\n      \"name\": \"Create YouTube API URL\",\n      \"type\": \"n8n-nodes-base.code\",\n      \"position\": [\n        1380,\n        -220\n      ],\n      \"parameters\": {\n        \"jsCode\": \"// Define the base URL for the YouTube Data API\\nconst BASE_URL = '{{ $env.API_BASE_URL }}';\\n\\n// Get all input items\\nconst items = $input.all();\\n\\n// Process each item and create YouTube URLs\\nconst results = items.map(item => {\\n    const VIDEO_ID = item.json.VIDEO_ID;\\n    const GOOGLE_API_KEY = item.json.GOOGLE_API_KEY;\\n\\n    if (!VIDEO_ID) {\\n        throw new Error('The video ID parameter is empty.');\\n    }\\n\\n    if (!GOOGLE_API_KEY) {\\n        throw new Error('The Google API Key is missing.');\\n    }\\n\\n    // Construct the API URL with the video ID and dynamically retrieved API key\\n    const youtubeUrl = `${BASE_URL}?part=snippet,contentDetails,status,statistics,player,topicDetails&id=${VIDEO_ID}&key=${GOOGLE_API_KEY}`;\\n\\n    return {\\n        json: {\\n            youtubeUrl: youtubeUrl\\n        }\\n    };\\n});\\n\\n// Return array of results\\nreturn results;\\n\\n\"\n      },\n      \"typeVersion\": 2,\n      \"notes\": \"This code node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"1941d169-f91f-4500-af55-deb7a5b2bc23\",\n      \"name\": \"Get YouTube Video Details\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"position\": [\n        1580,\n        -220\n      ],\n      \"parameters\": {\n        \"url\": \"{{ $env.BASE_URL }}\",\n        \"options\": {}\n      },\n      \"typeVersion\": 4.2,\n      \"notes\": \"This httpRequest node performs automated tasks as part of the workflow.\"","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Zie619/n8n-workflows/blob/94007c1445d9258a7da116646b79473e7c7c3282/workflows/Telegram/1982_Telegram_Splitout_Automation_Scheduled.json#L92-L128","documentation":"Multi-item variant of errors 100/104: the 'Create YouTube API URL' Code node maps over $input.all() and throws 'The video ID parameter is empty.' if ANY item lacks item.json.VIDEO_ID (or GOOGLE_API_KEY in the next check). Because map() aborts on the first bad item, one bad row in a scheduled batch fails the whole run.","triggerScenarios":"A scheduled trigger pulling a batch of rows where at least one row has a blank VIDEO_ID cell (sheet/DB), an upstream filter that should have excluded empty IDs not applied, or mixed-shape items after a merge node.","commonSituations":"Google Sheets/Airtable rows with optional video IDs, nightly cron jobs dying on one incomplete row, or a merge combining items from two sources where one source uses a different field name.","solutions":["Filter empty IDs upstream: add an IF/Filter node (VIDEO_ID is not empty) before this code node.","Inside the map, skip bad items instead of throwing: filter items first, then map; log skipped count.","If every item must have an ID, fix the source data and add NOT-empty/required constraints in the sheet/DB.","Pin the failing execution's input to identify which row was empty."],"exampleFix":"// before\nconst results = items.map(item => {\n    const VIDEO_ID = item.json.VIDEO_ID;\n    if (!VIDEO_ID) {\n        throw new Error('The video ID parameter is empty.');\n    }\n    // ...\n});\n\n// after - skip invalid rows, fail only if none remain\nconst valid = items.filter(i => i.json.VIDEO_ID && i.json.GOOGLE_API_KEY);\nif (valid.length < items.length) {\n  console.warn(`Skipped ${items.length - valid.length} items missing VIDEO_ID/GOOGLE_API_KEY`);\n}\nif (valid.length === 0) {\n  throw new Error('All items are missing VIDEO_ID or GOOGLE_API_KEY.');\n}\nconst results = valid.map(item => { /* unchanged URL construction */ });","handlingStrategy":"validation","validationCode":"const valid = items.filter(i => i.json.VIDEO_ID && i.json.GOOGLE_API_KEY);\nif (valid.length === 0) {\n  throw new Error('All items missing VIDEO_ID or GOOGLE_API_KEY — check the data source.');\n}\nconsole.warn(`Skipped ${items.length - valid.length} invalid items`);","typeGuard":"const hasRequiredFields = (item) =>\n  Boolean(item?.json?.VIDEO_ID && item?.json?.GOOGLE_API_KEY);","tryCatchPattern":null,"preventionTips":["Add a Filter node (VIDEO_ID is not empty) before the code node so bad rows never reach the map().","In scheduled batch jobs, skip-and-log invalid rows instead of throwing — one empty cell should not kill the nightly run.","Add data-source constraints (sheet validation, DB NOT NULL) so incomplete rows cannot exist."],"tags":["n8n","code-node","validation","youtube-api","batch","scheduled-trigger"],"backgroundTag":null,"analyzedSha":"94007c1445d9258a7da116646b79473e7c7c3282","analyzedAt":"2026-08-15T04:10:37.591Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}