DIYgod/RSSHub · warning · InvalidParameterError

Tweet ID is required

Error message

Tweet ID is required

What it means

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.

Source

Thrown at lib/routes/twitter/api/developer-api/api.ts:273

const getUserLikes = (id: string, params?: Record<string, any>) =>
    cacheTryGet(id, params, 'getUserLikes', async (id, params = {}) => {
        const client = await getAppClient();
        const response = await client.v2.get(`users/${id}/liked_tweets`, {
            max_results: params.count ?? 20,
            expansions: 'author_id,attachments.media_keys,referenced_tweets.id,referenced_tweets.id.author_id',
            'tweet.fields': 'created_at,entities,conversation_id,referenced_tweets,author_id,in_reply_to_user_id',
            'user.fields': 'username,name,profile_image_url,description',
            'media.fields': 'preview_image_url,url,type,width,height,variants',
        });
        return mapTweetResponseToLegacy(response);
    });

const getUserTweet = (id: string, params?: Record<string, any>) =>
    cacheTryGet(id, params, 'getUserTweet', async (_id, params = {}) => {
        const client = await getAppClient();
        const tweetId = params.focalTweetId;
        if (!tweetId) {
            throw new InvalidParameterError('Tweet ID is required');
        }
        const response = await client.v2.get(`tweets/${tweetId}`, {
            expansions: 'author_id,attachments.media_keys,referenced_tweets.id,referenced_tweets.id.author_id',
            'tweet.fields': 'created_at,entities,conversation_id,referenced_tweets,author_id,in_reply_to_user_id',
            'user.fields': 'username,name,profile_image_url,description',
            'media.fields': 'preview_image_url,url,type,width,height,variants',
        });
        return mapTweetResponseToLegacy({ data: response?.data ? [response.data] : [], includes: response?.includes });
    });

const getSearch = (keywords: string, params?: Record<string, any>) =>
    cache.tryGet(
        `twitter:search:${keywords}:${JSON.stringify(params)}`,
        async () => {
            const client = await getAppClient();
            const response = await client.v2.get('tweets/search/recent', {
                query: keywords,
                max_results: params?.count ?? 20,

View on GitHub (pinned to bed535e087)

Solutions

  1. Ensure the route/handler passes `focalTweetId` in the params when invoking getUserTweet.
  2. Validate params.focalTweetId is a non-empty string at the call site before delegating.
Defensive patterns

Strategy: validation

Validate before calling

if (!params?.focalTweetId) throw new InvalidParameterError('Tweet ID is required');

Type guard

const isTweetId = (v: unknown): v is string => typeof v === 'string' && /^\d+$/.test(v);

Prevention

When it happens

Trigger: 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.

Common situations: An upstream route refactor stopped forwarding focalTweetId; the caller passed a thread id but not the focal tweet id; params was defaulted to `{}`.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/0d70fafc79e6ae89. Report an issue: GitHub.