DIYgod/RSSHub · error · Error
Twitter API error: ${response.status}
Error message
Twitter API error: ${response.status} What it means
Generic Error thrown by twitterGot after the rate-limit/auth bookkeeping when response.status >= 400. It is the catch-all for any non-2xx Twitter response that was not already handled as 401/403/429 (those lock or delete the token but still propagate). The status code is embedded so the operator can see what Twitter returned.
Source
Thrown at lib/routes/twitter/api/web-api/utils.ts:236
// }
// }
// if (auth.password) {
// const passwordIndex = config.twitter.password?.indexOf(auth.password);
// if (passwordIndex !== undefined && passwordIndex !== -1) {
// config.twitter.password?.splice(passwordIndex, 1);
// }
// }
logger.debug(`twitter debug: delete twitter cookie for token ${auth.token} with status ${response.status}, remaining tokens: ${config.twitter.authToken?.length}`);
await cache.set(`${lockPrefix}${auth.token}`, '1', 3600);
// }
} else {
logger.debug(`twitter debug: unlock twitter cookie with success for token ${auth.token}`);
await cache.set(`${lockPrefix}${auth.token}`, '', 1);
}
}
if (response.status >= 400) {
throw new Error(`Twitter API error: ${response.status}`);
}
if (auth?.token) {
logger.debug(`twitter debug: update twitter cookie for token ${auth.token}`);
await cache.set(`twitter:cookie:${auth.token}`, JSON.stringify(dispatchers?.jar.serializeSync()), config.cache.contentExpire);
}
return responseData;
};
export const paginationTweets = async (endpoint: string, userId: number | undefined, variables: Record<string, any>, path?: string[]) => {
const params = {
variables: JSON.stringify({ ...variables, userId }),
features: JSON.stringify(gqlFeatures[endpoint]),
};
const fetchData = async () => {
if (config.twitter.thirdPartyApi && thirdPartySupportedAPI.includes(endpoint)) {View on GitHub (pinned to bed535e087)
Solutions
- Inspect the embedded status code in the message to classify the failure.
- For 5xx, retry after a short backoff (transient Twitter outage).
- For 400, update the GraphQL variables/endpoint in the route to match the current Twitter web client.
- Check RSSHub logs for the matching 'twitter debug' line showing the full response data and token state.
Defensive patterns
Strategy: retry
Type guard
function isTwitterApiError(e: unknown): e is Error {
return e instanceof Error && /Twitter API error: \d{3}/.test(e.message);
}
function twitterStatusFromError(e: Error): number | null {
const m = e.message.match(/(\d{3})$/); return m ? Number(m[1]) : null;
} Try / catch
try { await twitterGot(url, params); }
catch (e) {
const status = twitterStatusFromError(e as Error);
if (status && status >= 500) { await backoff(); retry(); } // transient
else if (status === 400) { /* schema changed; update route */ }
else throw e;
} Prevention
- Treat 5xx as transient with exponential backoff.
- Log the embedded status code so dashboards can separate Twitter outages from local issues.
- Watch for 400 storms — they signal an upstream GraphQL schema change requiring a route update.
When it happens
Trigger: Twitter returns 400 (bad GraphQL variables), 404 (endpoint moved), 5xx (Twitter outage), or any other 4xx/5xx not matched by the 401/403/429 branches. Also fires when a 429 slipped through because the rate-limit branch only locks the token but execution continues to this throw.
Common situations: Twitter API deprecation (variables schema changed → 400); Twitter-side incident (5xx); guest-token exhausted on an allowNoAuth path; downstream proxy returned a non-Twitter error status.
Related errors
- response.statusMessage
- response.statusMessage
- response.statusMessage
- Unable to access the Locals server function (${response.stat
- 日报数据不存在或为空
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/2968b1002b38a902.
Report an issue: GitHub.