{"record":{"id":"df9420b023dbb081","repo":"DIYgod/RSSHub","slug":"cannot-get-access-token-since-mangadex-client-id-o","errorCode":null,"errorMessage":"Cannot get access token since MangaDex client ID or secret is not set.","messagePattern":"Cannot get access token since MangaDex client ID or secret is not set\\.","errorType":"exception","errorClass":"ConfigNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/routes/mangadex/_access.ts","lineNumber":26,"sourceCode":"import constants from './_constants';\n\n/**\n * Retrieves an access token.\n *\n * @important Ensure the request includes a User-Agent header.\n * @throws {ConfigNotFoundError} If the required configuration is missing.\n * The following credentials are mandatory:\n * - `client ID` and `client secret`\n * - One of the following:\n *   - `username` and `password`\n *   - `refresh token`\n * @throws {FetchError} If the request fails.\n * - 400 Bad Request: If the `refresh token` or other credentials are invalid.\n * @returns {Promise<string>} A promise that resolves to the access token.\n */\nconst getToken = () => {\n    if (!config.mangadex.clientId || !config.mangadex.clientSecret) {\n        throw new ConfigNotFoundError('Cannot get access token since MangaDex client ID or secret is not set.');\n    }\n\n    return cache.tryGet(\n        'mangadex:access-token',\n        async () => {\n            if (!config.mangadex.refreshToken) {\n                return getAccessTokenByUserCredentials();\n            }\n\n            try {\n                return await getAccessTokenByRefreshToken();\n            } catch (error) {\n                if (error instanceof FetchError && error.statusCode === 400) {\n                    // If the refresh token is invalid, try to get a new one with the user credentials\n                    return getAccessTokenByUserCredentials();\n                }\n                throw error;\n            }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mangadex/_access.ts#L8-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"Fresh install; client credentials rotated and only one updated; env var name typo.","solutions":["Register an OAuth2 client on MangaDex and set both `MANGADEX_CLIENT_ID` and `MANGADEX_CLIENT_SECRET`.","Also set either `MANGADEX_REFRESH_TOKEN` or (`MANGADEX_USERNAME` + `MANGADEX_PASSWORD`) for the grant.","Restart RSSHub after setting the env vars."],"exampleFix":"// before: only client id set\nMANGADEX_CLIENT_ID=xxx\n\n// after\nMANGADEX_CLIENT_ID=xxx\nMANGADEX_CLIENT_SECRET=yyy\nMANGADEX_REFRESH_TOKEN=zzz","handlingStrategy":"validation","validationCode":"function mangadexClientConfigured(): boolean {\n    return Boolean(config.mangadex?.clientId && config.mangadex?.clientSecret);\n}\nif (!mangadexClientConfigured()) {\n    throw new Error('Set MANGADEX_CLIENT_ID and MANGADEX_CLIENT_SECRET');\n}","typeGuard":"function hasMangadexClient(c: typeof config): c is typeof config & { mangadex: { clientId: string; clientSecret: string } } {\n    return typeof c.mangadex?.clientId === 'string' && typeof c.mangadex?.clientSecret === 'string' && c.mangadex.clientId.length > 0 && c.mangadex.clientSecret.length > 0;\n}","tryCatchPattern":"import ConfigNotFoundError from '@/errors/types/config-not-found';\ntry {\n    await getToken();\n} catch (e) {\n    if (e instanceof ConfigNotFoundError && /client ID or secret is not set/.test(e.message)) {\n        return { disabled: true, reason: 'MANGADEX_CLIENT_ID / MANGADEX_CLIENT_SECRET not set' };\n    }\n    throw e;\n}","preventionTips":["Register an OAuth2 client on MangaDex and store both id and secret.","Validate mangadex config on boot.","Prefer refresh-token auth to avoid storing the password."],"tags":["config","missing-secret","oauth","mangadex"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}