DIYgod/RSSHub · error · ConfigNotFoundError
Cannot get access token since MangaDex refresh token is not
Error message
Cannot get access token since MangaDex refresh token is not set.
What it means
ConfigNotFoundError raised inside getAccessTokenByRefreshToken when config.mangadex.refreshToken is falsy. In the normal flow getToken routes falsy refreshToken to the username/password path (line 32), so this guard is effectively a defensive check that is only reachable if getAccessTokenByRefreshToken is invoked directly or config.mangadex.refreshToken becomes falsy between the two reads.
Source
Thrown at lib/routes/mangadex/_access.ts:90
const refreshToken = response?.data?.refresh_token;
const accessToken = response?.data?.access_token;
if (!refreshToken || !accessToken) {
throw new Error('Failed to retrieve refresh token from MangaDex API.');
}
config.mangadex.refreshToken = refreshToken; // cache the refresh token
return accessToken;
};
const getAccessTokenByRefreshToken = async () => {
if (!config.mangadex.clientId || !config.mangadex.clientSecret) {
throw new ConfigNotFoundError('Cannot get access token since MangaDex client ID or secret is not set.');
}
if (!config.mangadex.refreshToken) {
throw new ConfigNotFoundError('Cannot get access token since MangaDex refresh token is not set.');
}
const response = await got.post(constants.API.TOKEN, {
headers: {
'User-Agent': config.trueUA,
},
form: {
grant_type: 'refresh_token',
refresh_token: config.mangadex.refreshToken,
client_id: config.mangadex.clientId,
client_secret: config.mangadex.clientSecret,
},
});
const accessToken = response?.data?.access_token;
if (!accessToken) {
throw new Error('Failed to retrieve access token from MangaDex API.');
}View on GitHub (pinned to bed535e087)
Solutions
- If you intend to use the refresh-token flow, set MANGADEX_REFRESH_TOKEN to a valid token obtained from a prior password grant.
- Otherwise ensure MANGADEX_USERNAME and MANGADEX_PASSWORD are set so getToken takes the credentials path.
- Do not import getAccessTokenByRefreshToken directly; route all auth through the default getToken export.
- If you set refreshToken at runtime, do it before the first cache populate (key mangadex:access-token).
Defensive patterns
Strategy: validation
Validate before calling
const useRefreshFlow = Boolean(config.mangadex.refreshToken);
if (useRefreshFlow && (!config.mangadex.clientId || !config.mangadex.clientSecret)) {
throw new ConfigNotFoundError('Refresh-token flow needs MANGADEX_CLIENT_ID and MANGADEX_CLIENT_SECRET');
}
if (useRefreshFlow && !config.mangadex.refreshToken) {
// unreachable via getToken, but guard direct callers
throw new ConfigNotFoundError('Set MANGADEX_REFRESH_TOKEN or username/password');
} Type guard
const hasRefreshFlow = (c: typeof config): boolean =>
Boolean(c.mangadex?.refreshToken && c.mangadex?.clientId && c.mangadex?.clientSecret); Prevention
- Do not call getAccessTokenByRefreshToken directly; use getToken().
- If setting refreshToken at runtime, do so before the first cache.tryGet for mangadex:access-token.
- Keep username/password configured as a fallback even when using the refresh flow.
When it happens
Trigger: Direct invocation of getAccessTokenByRefreshToken with no MANGADEX_REFRESH_TOKEN configured; or a race where config.mangadex.refreshToken was truthy at getToken line 32 but cleared by the time line 89 runs (extremely unlikely given config is a synchronous singleton).
Common situations: Operator expected a refresh-token-only flow but never set MANGADEX_REFRESH_TOKEN; a custom route or test imported the non-exported function directly.
Related errors
- 缺少对应 loginUid 的 Bilibili 用户登录后的 Cookie 值 <a href="https://do
- GitHub Discussions RSS is disabled due to the lack of <a hre
- GitHub follower RSS is disabled due to the lack of <a href="
- GitHub notification RSS is disabled due to the lack of <a hr
- GitHub star RSS is disabled due to the lack of <a href="http
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/c91fcf194ecca6e8.
Report an issue: GitHub.