DIYgod/RSSHub · error · Error
Build ID not found.
Error message
Build ID not found.
What it means
Thrown by the TiDB blog route when the Next.js `buildId` cannot be regex-extracted from the fetched page HTML. The buildId is needed to construct the `_next/data/{buildId}/.../blog.json` API URL, so without it the route cannot proceed.
Source
Thrown at lib/routes/tidb/blog.ts:77
return `<blockquote>${parseContentToHtml(node.children)}</blockquote>`;
default:
return '';
}
})
.join('') ?? '';
export const handler = async (ctx: Context): Promise<Data> => {
const { category = 'latest' } = ctx.req.param();
const limit = Number(ctx.req.query('limit') ?? '20');
const baseUrl = 'https://tidb.net';
const targetUrl: string = new URL(`blog${category === 'latest' ? '' : `/c/${category}`}`, baseUrl).href;
const targetResponse = await ofetch(targetUrl);
const buildId: string | undefined = targetResponse.match(/"buildId":"(.*?)"/)?.[1];
if (!buildId) {
throw new Error('Build ID not found.');
}
const $: CheerioAPI = load(targetResponse);
const language = $('html').attr('lang') ?? 'zh';
const apiUrl: string = new URL(`_next/data/${buildId}/${language}/blog${category === 'latest' ? '' : `/c/${category}`}.json`, baseUrl).href;
const response = await ofetch(apiUrl, {
query: {
latest: true,
},
});
let items: DataItem[] = response.pageProps.blogs.content.slice(0, limit).map((item): DataItem => {
const title: string = item.title;
const description: string | undefined = item.summary;
const pubDate: number | string = item.publishedAt;
const linkUrl: string | undefined = item.slug ? `blog/${item.slug}` : undefined;View on GitHub (pinned to bed535e087)
Solutions
- Re-fetch https://tidb.net/blog in a browser and grep for `buildId` to confirm it still exists.
- If the buildId moved, update the regex on line 75 to the new serialization.
- If the site dropped Next.js data routes, switch to the new CMS/API the site exposes.
- Verify baseUrl and targetUrl resolve without a redirect.
Defensive patterns
Strategy: validation
Validate before calling
const targetResponse = await ofetch(targetUrl);
const buildId = targetResponse.match(/"buildId":"(.*?)"/)?.[1];
if (!buildId) throw new Error('TiDB page no longer exposes Next.js buildId — verify site front-end'); Type guard
const isBuildId = (v: unknown): v is string => typeof v === 'string' && /^[A-Za-z0-9_-]+$/.test(v);
Try / catch
try { /* handler body using buildId */ }
catch (e) { if (e instanceof Error && /Build ID/.test(e.message)) { /* surface 503 or fall back to HTML scraping */ } else throw e; } Prevention
- Watch TiDB.net deploys for front-end framework changes
- Add a smoke test that asserts buildId is parseable
- Fall back to scraping when _next/data is unavailable
When it happens
Trigger: ofetch(targetUrl) returns HTML that does not contain `"buildId":"..."` (line 75 regex misses), so line 78-80 throws a generic Error. Causes: site migrated off Next.js, served a static/error page, or changed the buildId serialization.
Common situations: TiDB.net deploys a non-Next.js front-end; a CDN serves a cached error page; the page requires a locale cookie and returns a redirect HTML without buildId.
Related errors
- missing next data
- 无法解析页面数据,请检查漫画 ID 是否正确或页面结构是否变动
- 无法解析页面 Props 数据
- 无法解析页面 HTML 数据,可能触发了反爬策略或页面结构巨变
- Failed to extract posts from the Next.js RSC payload
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/58a2b26092f9f8c7.
Report an issue: GitHub.