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
- 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.
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
- 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.
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
- Cannot get refresh token since MangaDex username or…
- Failed to retrieve access token from MangaDex API.
- Failed to retrieve refresh token from MangaDex API.
- Cannot get access token since MangaDex refresh token is not…
- Email Inbox RSS is disabled due to the lack of <a…
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)