DIYgod/RSSHub · error · TypeError
TechFlow API returned an invalid article list.
Error message
TechFlow API returned an invalid article list.
What it means
Thrown by the article-list fetcher when requestApi<ApiListResponse<Article>> succeeds (no anti-crawler string) but response.data is not an Array. The contract with GET /client/articles is that .data is the list of articles; a non-array means the API returned an error object, a paginated wrapper, or a shape change rather than a list.
Source
Thrown at lib/routes/techflowpost/utils.ts:154
updated: newsflash.updated_at ? parseDate(newsflash.updated_at) : undefined,
description: content || newsflash.abstract,
};
}
async function getArticleItems({ category, limit }: { category?: string; limit: string | number }) {
const link = `${rootUrl}/${locale}/article`;
const searchParams: Record<string, string | number> = {
page: 1,
page_size: limit,
};
if (category) {
searchParams.category_id = category;
}
const response = await requestApi<ApiListResponse<Article>>('/client/articles', link, searchParams);
if (!Array.isArray(response.data)) {
throw new TypeError('TechFlow API returned an invalid article list.');
}
return await Promise.all(
response.data.map((article) =>
cache.tryGet(`techflowpost:article:${article.id}`, async () => {
const itemLink = `${rootUrl}/${locale}/article/${article.id}`;
const detail = await requestApi<ArticleDetailResponse>(`/client/articles/${article.id}`, itemLink);
return getArticleItem(article, detail.article?.content);
})
)
);
}
async function getNewsflashItems(limit: string | number) {
const link = `${rootUrl}/${locale}/newsletter`;
const response = await requestApi<ApiListResponse<Newsflash>>('/client/newsflashes', link, {
page: 1,View on GitHub (pinned to bed535e087)
Solutions
- Inspect the actual response body (log response) to see whether the API now nests the array (e.g. response.data.list or response.data.items) and update the guard/parse accordingly.
- Confirm category_id is valid before sending it; an invalid category often yields an error object instead of a list.
- If the API genuinely returned an empty-but-valid list shape, check for a different list field name and update the ApiListResponse type plus the Array.isArray target.
- Add a defensive log of the raw response when Array.isArray fails so future shape changes are diagnosable instead of opaque.
Example fix
// before
if (!Array.isArray(response.data)) {
throw new TypeError('TechFlow API returned an invalid article list.');
}
// after: also accept a nested list and log the unexpected shape
const list = Array.isArray(response.data) ? response.data : response.data?.list;
if (!Array.isArray(list)) {
throw new TypeError(`TechFlow API returned an invalid article list: ${JSON.stringify(response).slice(0, 200)}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
function isArticleList(r: unknown): r is { data: unknown[] } {
return !!r && typeof r === 'object' && Array.isArray((r as any).data);
}
// const response = await requestApi<ApiListResponse<Article>>(...);
// if (!isArticleList(response)) { /* handle */ } Type guard
function isArticleListResponse(r: unknown): r is { data: Article[] } {
return typeof r === 'object' && r !== null && Array.isArray((r as { data?: unknown }).data);
} Try / catch
let response;
try {
response = await requestApi<ApiListResponse<Article>>('/client/articles', link, params);
} catch (e) {
if (e instanceof TypeError && /invalid article list/.test(e.message)) {
// log and degrade to empty feed instead of failing the route
return [];
}
throw e;
}
if (!isArticleListResponse(response)) { return []; } Prevention
- Treat the API envelope as unstable: validate with a type guard before use.
- Log raw responses when the shape check fails so contract changes are caught early.
- Pin the API version (or document the assumed endpoint) so an upstream rename is noticed.
- Validate category_id before sending it, since invalid ids often yield non-list responses.
When it happens
Trigger: Calling GET {apiRoot}/client/articles with page=1 and page_size=limit (optionally category_id) where the server replies with {code, msg, ...} or {data: {...}} instead of {data: [...]}. Also fires if the endpoint starts returning an object due to a category_id that resolves to a non-list response.
Common situations: TechFlow ships an API version bump that wraps lists differently; an invalid/deleted category_id makes the API return an error envelope that still HTTP-200s; ofetch/got auto-parses JSON so a temporary maintenance page served as JSON also lands here.
Related errors
- TechFlow API returned an invalid newsflash list.
- No articles found for category: ${category}
- 文章列表不存在或为空
- Category "${category}" not found
- Unsupported model: ${model}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/53c77c85164d552e.
Report an issue: GitHub.