Zie619/n8n-workflows · error · Error

Could not find __UNIVERSAL_DATA_FOR_REHYDRATION__ script in

Error message

Could not find __UNIVERSAL_DATA_FOR_REHYDRATION__ script in the HTML.

What it means

The third and earliest scraping failure in the 'Scrape raw video URL' node: the regex looking for <script id="__UNIVERSAL_DATA_FOR_REHYDRATION__" type="application/json"> found no match in the fetched HTML at all. This means the page returned is not a standard TikTok video page (or the script tag markup changed).

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

  1. Log a slice of the fetched HTML (e.g. html.slice(0, 500)) to identify what page actually came back (captcha, login, error).
  2. Add realistic browser headers (User-Agent, Accept-Language, Referer: https://www.tiktok.com/) and follow redirects on the upstream HTTP node.
  3. Confirm the input URL is a direct video URL (contains /video/<id> or a valid vt.tv/tiktok.com short link that resolves).
  4. If TikTok changed the marker, relax the regex to match on the id with any attribute order: /<script[^>]*id="__UNIVERSAL_DATA_FOR_REHYDRATION__"[^>]*>([\s\S]*?)<\/script>/.

Example fix

// before
const regex = /<script id="__UNIVERSAL_DATA_FOR_REHYDRATION__" type="application\/json">([\s\S]*?)<\/script>/;
const match = html.match(regex);

// after (attribute-order tolerant)
const regex = /<script[^>]*id="__UNIVERSAL_DATA_FOR_REHYDRATION__"[^>]*>([\s\S]*?)<\/script>/;
const match = html.match(regex);
if (!match) {
  throw new Error(`No hydration script found. Page starts with: ${html.slice(0, 200)}`);
}
Defensive patterns

Strategy: fallback

Validate before calling

const looksLikeVideoPage = /__UNIVERSAL_DATA_FOR_REHYDRATION__/.test(html) || /"webapp.video-detail"/.test(html);

Type guard

function extractHydrationJson(html) {
  const m = html.match(/<script[^>]*id="__UNIVERSAL_DATA_FOR_REHYDRATION__"[^>]*>([\s\S]*?)<\/script>/);
  return m ? m[1] : null;
}

Try / catch

try { JSON.parse(jsonStr); } catch (e) { throw new Error(`Hydration JSON malformed: ${e.message}`); }

Prevention

When it happens

Trigger: TikTok served a captcha/verify/bot-check interstitial, a login wall, a redirect page, or an error page instead of the video page; the upstream request went to a non-video URL (profile page, shortened link that wasn't resolved); TikTok changed the script tag's id, type attribute, or attribute order so the literal regex no longer matches.

Common situations: Scraping from server/datacenter IPs without browser headers; URL passed as a tiktok.com/@user short link that redirects to an HTML shell without hydration data; frontend deploy changing the hydration script id; n8n instance behind a proxy that strips or rewrites script tags.

Related errors


AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15). Data as JSON: /api/errors/4ffddc470c3c99b0. Report an issue: GitHub.