{"record":{"id":"387fc929382ed89d","repo":"DIYgod/RSSHub","slug":"twitter-api-is-not-configured-387fc9","errorCode":null,"errorMessage":"Twitter API is not configured","messagePattern":"Twitter API is not configured","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":503,"severity":"error","filePath":"lib/routes/twitter/api/index.ts","lineNumber":28,"sourceCode":"const enableWebApi = config.twitter.authToken;\nconst enableDeveloperApi = config.twitter.consumerKey && config.twitter.consumerSecret;\n\ntype ApiItem = (id: string, params?: Record<string, any>) => Promise<Record<string, any>> | Record<string, any> | null;\nlet api: {\n    init: () => void;\n    getUser: ApiItem;\n    getUserTweets: ApiItem;\n    getUserTweetsAndReplies: ApiItem;\n    getUserMedia: ApiItem;\n    getUserLikes: ApiItem;\n    getUserTweet: ApiItem;\n    getSearch: ApiItem;\n    getList: ApiItem;\n    getHomeTimeline: ApiItem;\n    getHomeLatestTimeline: ApiItem;\n} = {\n    init: () => {\n        throw new ConfigNotFoundError('Twitter API is not configured');\n    },\n    getUser: () => null,\n    getUserTweets: () => null,\n    getUserTweetsAndReplies: () => null,\n    getUserMedia: () => null,\n    getUserLikes: () => null,\n    getUserTweet: () => null,\n    getSearch: () => null,\n    getList: () => null,\n    getHomeTimeline: () => null,\n    getHomeLatestTimeline: () => null,\n};\n\nif (enableThirdPartyApi || enableWebApi) {\n    api = webApi;\n} else if (enableDeveloperApi) {\n    api = devApi;\n}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/twitter/api/index.ts#L10-L46","documentation":"ConfigNotFoundError from the Twitter API entrypoint's fallback stub: when neither the developer API, web API, nor third-party API is enabled, the `api` object stays as the placeholder whose `init()` throws. It is the top-level signal that no Twitter backend is configured.","triggerScenarios":"None of `config.twitter.consumerKey`+`consumerSecret`, `config.twitter.authToken`, or `config.twitter.thirdPartyApi` is set, so the conditional upgrades in api/index.ts never replace the stub; calling `init()` (or any getter that triggers init) throws on line 27-28.","commonSituations":"Fresh RSSHub install with no Twitter env vars; all previously-set tokens were removed; the env var names changed between versions.","solutions":["Configure at least one Twitter backend: developer API (consumer key/secret), web API (auth token), or third-party API base URL.","Restart RSSHub after setting the env vars so index.ts re-evaluates the enable flags.","If using a docker compose setup, confirm the env vars are passed into the container."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const enabled = config.twitter.consumerKey && config.twitter.consumerSecret || config.twitter.authToken || config.twitter.thirdPartyApi;\nif (!enabled) throw new ConfigNotFoundError('No Twitter backend configured — set developer keys, an auth token, or a third-party API');","typeGuard":"const hasTwitterBackend = (c: { consumerKey?: string; consumerSecret?: string; authToken?: string; thirdPartyApi?: string }): boolean => Boolean((c.consumerKey && c.consumerSecret) || c.authToken || c.thirdPartyApi);","tryCatchPattern":null,"preventionTips":["Validate at least one Twitter backend is configured at boot","Document all three backend options","Restart RSSHub after setting env vars"],"tags":["twitter","config","config-not-found","api-router","initialization"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}