DIYgod/RSSHub · error · ConfigNotFoundError

Cannot get access token since MangaDex client ID or secret…

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.

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.

Appendix: 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)