DIYgod/RSSHub · error · Error
Failed to extract required data from JSON
Error message
Failed to extract required data from JSON
What it means
Thrown after the SSR_HYDRATED_DATA script content is parsed into JSON but the expected AuthorVideoList.videoList or AuthorDetailInfo fields are absent. The route destructures these two paths from the parsed object; if either is falsy the feed cannot be built. This indicates the JSON shape changed or the regex captured an incomplete/truncated object.
Source
Thrown at lib/routes/ixigua/user-video.tsx:55
const url = `${host}/home/${uid}/?wid_try=1`;
const { data } = await got(url);
const $ = load(data);
const jsData = $('#SSR_HYDRATED_DATA').html();
if (!jsData) {
throw new Error('Failed to find SSR_HYDRATED_DATA');
}
const jsonData = JSON.parse(jsData.match(/var\s+data\s*=\s*(\{.*?\});/s)?.[1].replaceAll('undefined', 'null') || '{}');
const {
AuthorVideoList: { videoList: videoInfos },
AuthorDetailInfo: userInfo,
} = jsonData;
if (!videoInfos || !userInfo) {
throw new Error('Failed to extract required data from JSON');
}
return {
title: `${userInfo.name} 的西瓜视频`,
link: url,
description: userInfo.introduce,
item: videoInfos.map((i) => ({
title: i.title,
description: renderToString(<IxiguaVideoDescription i={i} disableEmbed={disableEmbed} />),
link: `${host}/${i.groupId}`,
pubDate: parseDate(i.publishTime * 1000),
author: userInfo.name,
})),
};
}
const IxiguaVideoDescription = ({ i, disableEmbed }: { i: any; disableEmbed?: string }) => (
<>View on GitHub (pinned to bed535e087)
Solutions
- Inspect the full jsData string to confirm whether AuthorVideoList and AuthorDetailInfo keys exist — if present but missed, the regex is truncating; switch to a balanced-brace extraction or parse the whole script body.
- If the keys were renamed, update the destructuring to match the new field names.
- Differentiate between 'no videos' and 'missing data' — return an empty feed (allowEmpty) for users with no videos instead of throwing.
- Log the top-level keys of jsonData when the guard fires to accelerate diagnosis.
Example fix
// before
const jsonData = JSON.parse(jsData.match(/var\s+data\s*=\s*(\{.*?\});/s)?.[1].replaceAll('undefined', 'null') || '{}');
// after — extract the full balanced object instead of a non-greedy truncation
const start = jsData.indexOf('{');
let depth = 0, end = -1;
for (let i = start; i < jsData.length; i++) {
if (jsData[i] === '{') depth++;
else if (jsData[i] === '}') { depth--; if (depth === 0) { end = i; break; } }
}
const jsonData = JSON.parse(jsData.slice(start, end + 1).replaceAll('undefined', 'null')); Defensive patterns
Strategy: type-guard
Validate before calling
// After parsing, verify the expected keys exist before destructuring
const jsonData = JSON.parse(rawJson);
if (!('AuthorVideoList' in jsonData) || !('AuthorDetailInfo' in jsonData)) {
throw new Error(`Unexpected ixigua JSON shape. Top-level keys: ${Object.keys(jsonData).join(', ')}`);
} Type guard
interface IxiguaData {
AuthorVideoList: { videoList: unknown[] };
AuthorDetailInfo: { name: string; introduce?: string };
}
function isIxiguaData(d: unknown): d is IxiguaData {
return typeof d === 'object' && d !== null &&
'AuthorVideoList' in d && 'AuthorDetailInfo' in d &&
Array.isArray((d as any).AuthorVideoList?.videoList);
} Try / catch
try {
const jsonData = JSON.parse(jsData);
if (!isIxiguaData(jsonData)) {
throw new Error('Failed to extract required data from JSON');
}
// ...use jsonData with full type safety
} catch (e) {
throw new Error(`ixigua JSON parse failed: ${(e as Error).message}`, { cause: e });
} Prevention
- Use a balanced-brace extractor instead of a non-greedy regex to avoid truncated JSON.
- Define a TypeScript interface for the expected payload and type-guard before destructuring.
- Log top-level keys on failure to detect upstream schema changes early.
- Distinguish 'user has zero videos' (empty array) from 'data missing' (undefined) — the former should not error.
When it happens
Trigger: The regex /var\s+data\s*=\s*(\{.*?\});/s uses a non-greedy match that stops at the first '} ;' sequence, which can truncate a deeply nested object and yield partial JSON missing the AuthorVideoList/AuthorDetailInfo keys. Also fires when the user genuinely has no videos (videoList is empty/undefined in the SSR payload) or when ixigua renames these keys in a frontend version bump.
Common situations: ixigua restructures its SSR data and renames AuthorVideoList to a different key. A user with a brand-new or deactivated account has an empty video list. The regex's non-greedy quantifier captures only the first nested object, losing the rest of the payload.
Related errors
- Invalid Engine Value: ${engine}, please check your config.
- 无法获取最新的 year 和 issue
- Invalid domain
- Invalid number
- Invalid domain
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/73daa6318f22ed95.
Report an issue: GitHub.