DIYgod/RSSHub · error · ConfigNotFoundError

No valid Twitter token found

Error message

No valid Twitter token found

What it means

ConfigNotFoundError thrown by twitterGot when getAuth(30) returns nothing and the caller did not set allowNoAuth. RSSHub requires at least one TWITTER_AUTH_TOKEN (or the deprecated consumer-key config) to call authenticated GraphQL endpoints; with no token and no opt-out, the request cannot be made.

Source

Thrown at lib/routes/twitter/api/web-api/utils.ts:87

    return {
        token,
        // username: config.twitter.username?.[index],
        // password: config.twitter.password?.[index],
        // authenticationSecret: config.twitter.authenticationSecret?.[index],
    };
};

export const twitterGot = async (
    url,
    params,
    options?: {
        allowNoAuth?: boolean;
    }
) => {
    const auth = await getAuth(30);

    if (!auth && !options?.allowNoAuth) {
        throw new ConfigNotFoundError('No valid Twitter token found');
    }

    const requestUrl = `${url}?${queryString.stringify(params)}`;

    let cookie: string | Record<string, any> | null | undefined = await token2Cookie(auth?.token);
    // if (!cookie && auth) {
    //     cookie = await login({
    //         username: auth.username,
    //         password: auth.password,
    //         authenticationSecret: auth.authenticationSecret,
    //     });
    // }
    let dispatchers:
        | {
              jar: CookieJar;
              agent: CookieAgent | ProxyAgent;
          }
        | undefined;

View on GitHub (pinned to bed535e087)

Solutions

  1. Set TWITTER_AUTH_TOKEN (one or more, comma-separated) in the RSSHub environment to a valid x.com browser cookie auth token.
  2. Restart RSSHub so config is re-read.
  3. If tokens are merely locked, wait for the lock TTL (up to 2000s for rate-limit, 3600s for auth-failure) to expire or clear the lockPrefix cache keys.
  4. Verify the token still works by logging into x.com with that cookie.

Example fix

// before: env not set
// TWITTER_AUTH_TOKEN=
// after
// TWITTER_AUTH_TOKEN=abcdef0123...  (cookie 'auth_token' from x.com)
Defensive patterns

Strategy: validation

Validate before calling

function hasTwitterToken(cfg: any): boolean {
  return Array.isArray(cfg?.twitter?.authToken) && cfg.twitter.authToken.filter(Boolean).length > 0;
}
// call before serving any authenticated twitter route
if (!hasTwitterToken(config)) { /* return a friendly 'not configured' page */ }

Type guard

function isAuthObject(auth: unknown): auth is { token: string } {
  return typeof auth === 'object' && auth !== null && typeof (auth as any).token === 'string';
}

Try / catch

try { await twitterGot(url, params); }
catch (e) {
  if (/No valid Twitter token/.test(String(e))) { /* alert ops: add tokens or wait out locks */ }
  else throw e;
}

Prevention

When it happens

Trigger: Any authenticated Twitter route (user timeline, lists, media, etc.) is requested while config.twitter.authToken is empty/unset, all tokens are locked (rate-limited) for the next 30 retries, or all tokens were spliced out due to repeated 401/403. allowNoAuth is only true for the unauthenticated user-id-lookup path.

Common situations: Fresh RSSHub deploy without TWITTER_AUTH_TOKEN configured; all tokens burned by heavy use and now locked in cache; tokens expired/revoked by Twitter; misconfigured env var name so the array stays empty.

Related errors


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