{"record":{"id":"2739875191879fe0","repo":"Zie619/n8n-workflows","slug":"the-video-id-parameter-is-empty","errorCode":null,"errorMessage":"The video ID parameter is empty.","messagePattern":"The video ID parameter is empty\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"workflows/Code/1313_Code_HTTP_Automation_Webhook.json","lineNumber":639,"sourceCode":"            }\n          ]\n        },\n        \"responseMode\": \"lastNode\",\n        \"formDescription\": \"This workflow allows you to extract various types of actionable information from YouTube videos that is audience specific using dynamically composed prompts.\"\n      },\n      \"typeVersion\": 2.2,\n      \"notes\": \"This formTrigger node performs automated tasks as part of the workflow.\"\n    },\n    {\n      \"id\": \"c63d236c-99d5-43f6-825e-836ddd41ad6f\",\n      \"name\": \"Create YouTube API URL\",\n      \"type\": \"n8n-nodes-base.code\",\n      \"position\": [\n        3100,\n        100\n      ],\n      \"parameters\": {\n        \"jsCode\": \"// Define the base URL for the YouTube Data API\\nconst BASE_URL = '{{ $env.API_BASE_URL }}';\\n\\n// Get the first input item\\nconst item = $input.first();\\n\\n// Extract the videoId and google_api_key from the input JSON\\nconst VIDEO_ID = item.json.video_id;\\nconst GOOGLE_API_KEY = item.json.google_api_key; // Dynamically retrieve API key\\n\\nif (!VIDEO_ID) {\\n  throw new Error('The video ID parameter is empty.');\\n}\\n\\nif (!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\\nconst youtubeUrl = `${BASE_URL}?part=snippet,contentDetails,status,statistics,player,topicDetails&id=${VIDEO_ID}&key=${GOOGLE_API_KEY}`;\\n\\n// Return the constructed URL\\nreturn [\\n  {\\n    json: {\\n      youtubeUrl: youtubeUrl,\\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\": \"17daf9d1-4bee-4632-b929-0696e71b9fa2\",\n      \"name\": \"Get YouTube Video Details\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"position\": [\n        3440,\n        100\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":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/Zie619/n8n-workflows/blob/94007c1445d9258a7da116646b79473e7c7c3282/workflows/Code/1313_Code_HTTP_Automation_Webhook.json#L621-L657","documentation":"Thrown by the 'Create YouTube API URL' Code node before any HTTP call is made. The node reads video_id and google_api_key from the first input item (produced by an upstream form trigger) and refuses to build the YouTube Data API URL when video_id is falsy. This is a deliberate fail-fast guard, not a YouTube API error.","triggerScenarios":"The form/webhook submission omits the video_id field, sends it empty, or sends it under a different key (videoId, url instead of video_id). Also fires when a full YouTube URL is pasted instead of the bare 11-character ID, only if the field name mismatches — a pasted URL in video_id would pass this guard but fail later at the API.","commonSituations":"Form field renamed or remapped in the n8n Form Trigger; user submits without filling the field (field not marked required); upstream node outputs a different JSON shape (e.g. data nested under body or query); whitespace-only input.","solutions":["Make video_id a required field on the form/webhook trigger and resubmit with the 11-character YouTube video ID.","Log $input.first().json in the node to confirm the exact payload shape and field name the upstream node emits.","Normalize input defensively: trim the value and, if a full URL was pasted, extract the ID with a regex before validating.","Add an IF/error branch before this node that returns a friendly 'video ID required' response to the submitter instead of a thrown error."],"exampleFix":"// before\nconst VIDEO_ID = item.json.video_id;\nif (!VIDEO_ID) {\n  throw new Error('The video ID parameter is empty.');\n}\n\n// after\nconst raw = (item.json.video_id ?? item.json.videoId ?? '').toString().trim();\nconst VIDEO_ID = raw.match(/(?:v=|youtu\\.be\\/|shorts\\/)([\\w-]{11})/)?.[1] || (raw.length === 11 ? raw : '');\nif (!VIDEO_ID) {\n  throw new Error(`The video ID parameter is empty or invalid. Got: ${JSON.stringify(raw)}`);\n}","handlingStrategy":"validation","validationCode":"const raw = String(item.json.video_id ?? '').trim();\nconst VIDEO_ID = raw.match(/(?:v=|youtu\\.be\\/|shorts\\/)([\\w-]{11})/)?.[1] || (raw.length === 11 ? raw : '');\nif (!VIDEO_ID) {\n  return [{ json: { error: 'video_id required: submit the 11-character YouTube video ID or a full URL' } }];\n}","typeGuard":"function extractYouTubeId(v) {\n  const s = String(v ?? '').trim();\n  if (/^[\\w-]{11}$/.test(s)) return s;\n  return s.match(/(?:v=|youtu\\.be\\/|shorts\\/|embed\\/)([\\w-]{11})/)?.[1] ?? null;\n}","tryCatchPattern":null,"preventionTips":["Mark video_id required on the form trigger.","Accept both full URLs and bare IDs by normalizing with a regex before validating.","Validate at the trigger/IF-node level and respond to the submitter instead of throwing mid-workflow.","Pin the expected payload shape with a quick Object.keys log during development."],"tags":["n8n","youtube-api","validation","code-node","form-input"],"backgroundTag":null,"analyzedSha":"94007c1445d9258a7da116646b79473e7c7c3282","analyzedAt":"2026-08-15T04:10:37.591Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}