DIYgod/RSSHub · error · ConfigNotFoundError

Cannot get access token since MangaDex client ID or secret i

Error message

Cannot get access token since MangaDex client ID or secret is not set.

What it means

Thrown by `getToken` (lib/routes/mangadex/_access.ts:26) as a `ConfigNotFoundError` when either `config.mangadex.clientId` or `config.mangadex.clientSecret` is unset. These are the OAuth2 client credentials MangaDex requires for every token request, so the route cannot authenticate at all without them.

Source

Thrown at lib/routes/mangadex/_access.ts:26

import constants from './_constants';

/**
 * Retrieves an access token.
 *
 * @important Ensure the request includes a User-Agent header.
 * @throws {ConfigNotFoundError} If the required configuration is missing.
 * The following credentials are mandatory:
 * - `client ID` and `client secret`
 * - One of the following:
 *   - `username` and `password`
 *   - `refresh token`
 * @throws {FetchError} If the request fails.
 * - 400 Bad Request: If the `refresh token` or other credentials are invalid.
 * @returns {Promise<string>} A promise that resolves to the access token.
 */
const getToken = () => {
    if (!config.mangadex.clientId || !config.mangadex.clientSecret) {
        throw new ConfigNotFoundError('Cannot get access token since MangaDex client ID or secret is not set.');
    }

    return cache.tryGet(
        'mangadex:access-token',
        async () => {
            if (!config.mangadex.refreshToken) {
                return getAccessTokenByUserCredentials();
            }

            try {
                return await getAccessTokenByRefreshToken();
            } catch (error) {
                if (error instanceof FetchError && error.statusCode === 400) {
                    // If the refresh token is invalid, try to get a new one with the user credentials
                    return getAccessTokenByUserCredentials();
                }
                throw error;
            }

View on GitHub (pinned to bed535e087)

Solutions

  1. Register an OAuth2 client on MangaDex and set both `MANGADEX_CLIENT_ID` and `MANGADEX_CLIENT_SECRET`.
  2. Also set either `MANGADEX_REFRESH_TOKEN` or (`MANGADEX_USERNAME` + `MANGADEX_PASSWORD`) for the grant.
  3. Restart RSSHub after setting the env vars.

Example fix

// before: only client id set
MANGADEX_CLIENT_ID=xxx

// after
MANGADEX_CLIENT_ID=xxx
MANGADEX_CLIENT_SECRET=yyy
MANGADEX_REFRESH_TOKEN=zzz
Defensive patterns

Strategy: validation

Validate before calling

function mangadexClientConfigured(): boolean {
    return Boolean(config.mangadex?.clientId && config.mangadex?.clientSecret);
}
if (!mangadexClientConfigured()) {
    throw new Error('Set MANGADEX_CLIENT_ID and MANGADEX_CLIENT_SECRET');
}

Type guard

function hasMangadexClient(c: typeof config): c is typeof config & { mangadex: { clientId: string; clientSecret: string } } {
    return typeof c.mangadex?.clientId === 'string' && typeof c.mangadex?.clientSecret === 'string' && c.mangadex.clientId.length > 0 && c.mangadex.clientSecret.length > 0;
}

Try / catch

import ConfigNotFoundError from '@/errors/types/config-not-found';
try {
    await getToken();
} catch (e) {
    if (e instanceof ConfigNotFoundError && /client ID or secret is not set/.test(e.message)) {
        return { disabled: true, reason: 'MANGADEX_CLIENT_ID / MANGADEX_CLIENT_SECRET not set' };
    }
    throw e;
}

Prevention

When it happens

Trigger: Deploying RSSHub without `MANGADEX_CLIENT_ID`/`MANGADEX_CLIENT_SECRET`; one set, the other omitted; config schema not exposing the keys; running a Mangadex route for the first time without registering an OAuth client.

Common situations: Fresh install; client credentials rotated and only one updated; env var name typo.

Related errors


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