{"record":{"id":"0d70fafc79e6ae89","repo":"DIYgod/RSSHub","slug":"tweet-id-is-required","errorCode":null,"errorMessage":"Tweet ID is required","messagePattern":"Tweet ID is required","errorType":"exception","errorClass":"InvalidParameterError","httpStatus":503,"severity":"warning","filePath":"lib/routes/twitter/api/developer-api/api.ts","lineNumber":273,"sourceCode":"const getUserLikes = (id: string, params?: Record<string, any>) =>\n    cacheTryGet(id, params, 'getUserLikes', async (id, params = {}) => {\n        const client = await getAppClient();\n        const response = await client.v2.get(`users/${id}/liked_tweets`, {\n            max_results: params.count ?? 20,\n            expansions: 'author_id,attachments.media_keys,referenced_tweets.id,referenced_tweets.id.author_id',\n            'tweet.fields': 'created_at,entities,conversation_id,referenced_tweets,author_id,in_reply_to_user_id',\n            'user.fields': 'username,name,profile_image_url,description',\n            'media.fields': 'preview_image_url,url,type,width,height,variants',\n        });\n        return mapTweetResponseToLegacy(response);\n    });\n\nconst getUserTweet = (id: string, params?: Record<string, any>) =>\n    cacheTryGet(id, params, 'getUserTweet', async (_id, params = {}) => {\n        const client = await getAppClient();\n        const tweetId = params.focalTweetId;\n        if (!tweetId) {\n            throw new InvalidParameterError('Tweet ID is required');\n        }\n        const response = await client.v2.get(`tweets/${tweetId}`, {\n            expansions: 'author_id,attachments.media_keys,referenced_tweets.id,referenced_tweets.id.author_id',\n            'tweet.fields': 'created_at,entities,conversation_id,referenced_tweets,author_id,in_reply_to_user_id',\n            'user.fields': 'username,name,profile_image_url,description',\n            'media.fields': 'preview_image_url,url,type,width,height,variants',\n        });\n        return mapTweetResponseToLegacy({ data: response?.data ? [response.data] : [], includes: response?.includes });\n    });\n\nconst getSearch = (keywords: string, params?: Record<string, any>) =>\n    cache.tryGet(\n        `twitter:search:${keywords}:${JSON.stringify(params)}`,\n        async () => {\n            const client = await getAppClient();\n            const response = await client.v2.get('tweets/search/recent', {\n                query: keywords,\n                max_results: params?.count ?? 20,","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/twitter/api/developer-api/api.ts#L255-L291","documentation":"InvalidParameterError from getUserTweet in the Twitter developer API: the function reads `params.focalTweetId` and requires it to call `tweets/{tweetId}`. If the caller omitted focalTweetId, there is nothing to fetch, so it throws.","triggerScenarios":"getUserTweet is invoked with a params object that has no `focalTweetId` field — line 274-275 detects the missing id and throws before the v2 GET.","commonSituations":"An upstream route refactor stopped forwarding focalTweetId; the caller passed a thread id but not the focal tweet id; params was defaulted to `{}`.","solutions":["Ensure the route/handler passes `focalTweetId` in the params when invoking getUserTweet.","Validate params.focalTweetId is a non-empty string at the call site before delegating."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!params?.focalTweetId) throw new InvalidParameterError('Tweet ID is required');","typeGuard":"const isTweetId = (v: unknown): v is string => typeof v === 'string' && /^\\d+$/.test(v);","tryCatchPattern":null,"preventionTips":["Require focalTweetId in the route's parameter schema","Fail fast at the call site with a clear message","Add a unit test for the missing-id path"],"tags":["twitter","invalid-parameter","validation","developer-api","missing-argument"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}