DIYgod/RSSHub · error · NotFoundError

User ID not found

Error message

User ID not found

What it means

Thrown by getUserId after iterating every `<script data-sjs>` tag on a Threads profile and finding no JSONPath `$..user_id` match. It means Threads did not embed the user id payload in the expected SJS scripts, so the cache factory function gives up with a NotFoundError.

Source

Thrown at lib/routes/threads/utils.ts:79

        const dom = new JSDOM(response);
        const { document } = dom.window;

        for (const el of document.querySelectorAll('script[data-sjs]')) {
            try {
                const data = JSONPath({
                    path: '$..user_id',
                    json: JSON.parse(el.textContent || ''),
                });

                if (data?.[0]) {
                    return data[0];
                }
            } catch {
                // Skip invalid JSON
            }
        }

        throw new NotFoundError('User ID not found');
    });

    if (result) {
        if (typeof result === 'string') {
            return result;
        }
        if (typeof result === 'number') {
            return result.toString();
        }
    }
    throw new TypeError('Invalid user ID type');
};

const hasMedia = (post) => post.image_versions2 || post.carousel_media || post.video_versions;

const buildMedia = (post) => {
    let html = '';

View on GitHub (pinned to bed535e087)

Solutions

  1. Open the profile URL with the exact headers and inspect `script[data-sjs]` contents to confirm `user_id` is still present.
  2. Broaden the JSONPath or add a fallback selector if Threads moved the id into a different script type.
  3. Detect login/interstitial HTML early and throw a clearer error distinguishing 'profile not found' from 'page structure changed'.
  4. Invalidate the cache key `threads:userId:{user}` if you previously stored a bad value.
Defensive patterns

Strategy: try-catch

Validate before calling

const html = await ofetch(profileUrl(user), { headers });
const hasSjs = /<script[^>]*data-sjs[^>]*>/.test(html);
if (!hasSjs) throw new Error('Threads profile page has no data-sjs scripts');

Type guard

const hasUserId = (o: unknown): boolean => JSONPath({ path: '$..user_id', json: o as object }).length > 0;

Try / catch

try { const id = await getUserId(user); /* use id */ }
catch (e) { if (e instanceof NotFoundError && /User ID/.test(e.message)) { /* surface as 404 or retry */ } else throw e; }

Prevention

When it happens

Trigger: The Threads profile HTML has no `script[data-sjs]` elements carrying a `user_id` field, or all such scripts fail JSON.parse and fall into the catch on line 74. The result is cached (or not) and then surfaced to the caller.

Common situations: Threads shipped a new bundle that renames user_id, the profile does not exist (404 page still 200s with minimal HTML), or the response is a login/consent interstitial. A stale positive cache entry masking this is also possible but here the cache factory itself throws.

Related errors


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