Zie619/n8n-workflows · error · Error
HTML body is undefined. Check the previous node's output.
Error message
HTML body is undefined. Check the previous node's output.
What it means
Thrown by the 'Scrape raw video URL' Code node in a TikTok video-download workflow. The node expects the previous HTTP Request node to expose the page HTML under json.data. When that field is undefined (request failed, response shape differs, or the HTTP node put the body under a different key), the guard fires before any regex scraping happens.
Source
Thrown at workflows/Code/1802_Code_Manual_Import_Webhook.json:76
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124"
}
]
}
},
"typeVersion": 4.2,
"notes": "This httpRequest node performs automated tasks as part of the workflow."
},
{
"id": "734a5304-f67f-4ace-a1da-0d268664452c",
"name": "Scrape raw video URL",
"type": "n8n-nodes-base.code",
"position": [
480,
20
],
"parameters": {
"jsCode": "const html = $input.first().json.data;\nconst headers = $input.first().json.headers || {};\nconst cookies = headers['set-cookie'] || [];\n\nif (!html) {\n throw new Error(\"HTML body is undefined. Check the previous node's output.\");\n}\nconst regex = /<script id=\"__UNIVERSAL_DATA_FOR_REHYDRATION__\" type=\"application\\/json\">([\\s\\S]*?)<\\/script>/;\nconst match = html.match(regex);\n\nif (match) {\n const jsonStr = match[1];\n const data = JSON.parse(jsonStr);\n const videoUrl = data?.__DEFAULT_SCOPE__?.[\"webapp.video-detail\"]?.itemInfo?.itemStruct?.video?.playAddr;\n if (!videoUrl) {\n throw new Error(\"Could not find video URL in the JSON data.\");\n }\n return [{ json: { videoUrl, cookies: cookies.join('; ') } }];\n} else {\n throw new Error(\"Could not find __UNIVERSAL_DATA_FOR_REHYDRATION__ script in the HTML.\");\n}"
},
"typeVersion": 2,
"notes": "This code node performs automated tasks as part of the workflow."
},
{
"id": "f574ccb8-6f5f-4e55-a2d5-7ad775d3c4e5",
"name": "Output video file without watermark",
"type": "n8n-nodes-base.httpRequest",
"position": [
900,
20
],
"parameters": {
"url": "{{ $env.BASE_URL }}",
"options": {
"response": {
"response": {
"responseFormat": "file"View on GitHub (pinned to 94007c1445)
Solutions
- Check the upstream HTTP Request node's execution output to see where the HTML actually landed (json.data vs json.body vs json.data.body).
- Set the HTTP node Response Format to 'Text/String' (or 'autodetect' with the body expected as a string) so the HTML arrives as json.data.
- Add a User-Agent header and verify the request returns 200 — a 403/captcha page will still be defined but fail later scraping, while a rejected request can yield undefined.
- Guard with a clearer message that dumps Object.keys($input.first().json) to diagnose shape drift.
Example fix
// before
const html = $input.first().json.data;
if (!html) {
throw new Error("HTML body is undefined. Check the previous node's output.");
}
// after
const first = $input.first().json;
const html = first.data ?? first.body ?? first.data?.body;
if (typeof html !== 'string' || html.length === 0) {
throw new Error(`HTML body is undefined. Available keys: ${Object.keys(first).join(', ')}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
const first = $input.first().json; const html = first.data ?? first.body ?? first.data?.body; const ok = typeof html === 'string' && html.length > 0;
Type guard
function hasHtmlBody(j) {
const b = j?.data ?? j?.body ?? j?.data?.body;
return typeof b === 'string' && b.length > 0;
} Prevention
- Set the upstream HTTP node's Response Format to Text so the body lands at json.data as a string.
- Send browser-like headers (User-Agent) so the target returns real HTML.
- Check the HTTP node's own 'on fail' setting — fail there with its status code, not later in the parser.
- Log Object.keys of the input json whenever shape drift is possible.
When it happens
Trigger: The upstream HTTP Request node returned an error response or was configured with responseFormat 'autodetect'/'json' so the raw body is not at json.data; the request was blocked (403/captcha) and returned an error object; the response property name differs (e.g. json.body, json.data.body for n8n's full-response option).
Common situations: HTTP node 'Response Format' set to JSON instead of Text/String; 'Include Response Headers and Status' toggled, nesting the body under data.body; TikTok blocking the request (bot detection, missing User-Agent) so the body is empty; workflow imported from another instance where the HTTP node version/options differ.
Related errors
- Could not find video URL in the JSON data.
- Could not find __UNIVERSAL_DATA_FOR_REHYDRATION__ script in
- Invalid input data format
- Initial Vector 'data' is undefined or missing.
- Initial Vector 'data' is in an unsupported format.
AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15).
Data as JSON: /api/errors/6d35d96bf6358ba2.
Report an issue: GitHub.