{"record":{"id":"9429f523186f76bd","repo":"DIYgod/RSSHub","slug":"failed-to-retrieve-user-settings-from-mangadex-api","errorCode":null,"errorMessage":"Failed to retrieve user settings from MangaDex API.","messagePattern":"Failed to retrieve user settings from MangaDex API\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/mangadex/_profile.ts","lineNumber":24,"sourceCode":"import getToken from './_access';\nimport constants from './_constants';\n\nconst getSetting = async () => {\n    const accessToken = await getToken();\n\n    return cache.tryGet(\n        'mangadex:settings',\n        async () => {\n            const response = await got.get(constants.API.SETTING, {\n                headers: {\n                    Authorization: `Bearer ${accessToken}`,\n                    'User-Agent': config.trueUA,\n                },\n            });\n\n            const setting = response?.data?.settings;\n            if (!setting) {\n                throw new Error('Failed to retrieve user settings from MangaDex API.');\n            }\n\n            return setting;\n        },\n        config.cache.contentExpire,\n        false\n    );\n};\n\nconst getFilteredLanguages = async (ingoreConfigNotFountError: boolean = true) => {\n    try {\n        const settings = (await getSetting()) as any;\n        return settings.userPreferences.filteredLanguages as string[];\n    } catch (error) {\n        if (ingoreConfigNotFountError && error instanceof ConfigNotFoundError) {\n            return [];\n        }\n        throw error;","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mangadex/_profile.ts#L6-L42","documentation":"Thrown when GET /settings (requires Bearer access token) returns a body without a settings field. Used to derive the user's filtered/excluded languages, so a failure here breaks every MangaDex route that depends on reading-status or language filtering.","triggerScenarios":"GET https://api.mangadex.org/settings with Authorization: Bearer <accessToken> where response.data.settings is undefined. Caused by a missing/invalid/expired access token (401 returned in body), the settings endpoint being down, or an account with no settings object yet.","commonSituations":"MANGADEX_* auth env unset so accessToken is empty; access token cache (mangadex:access-token) holds a stale token past the 15-min TTL; MangaDex settings API temporarily unavailable; user account in a state that returns no settings.","solutions":["Ensure MANGADEX_CLIENT_ID/SECRET plus username/password (or refresh token) are set so getToken can mint an access token.","Flush the cache key mangadex:access-token to force a fresh token on next request.","Confirm https://api.mangadex.org/settings works with the same token via curl.","If getFilteredLanguages is optional for your route, call it with ignoreConfigNotFoundError=false and degrade gracefully."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!config.mangadex.clientId || !config.mangadex.clientSecret) {\n    // settings endpoint requires auth; skip language filtering instead of crashing\n    return [];\n}","typeGuard":"interface SettingsResponse { settings?: Record<string, unknown>; }\nconst hasSettings = (v: unknown): v is SettingsResponse =>\n    typeof v === 'object' && v !== null && typeof (v as SettingsResponse).settings === 'object';","tryCatchPattern":"try {\n    settings = await getSetting();\n} catch (e) {\n    // getFilteredLanguages already supports ignoreConfigNotFoundError; degrade to defaults\n    settings = {};\n}","preventionTips":["Treat the settings endpoint as best-effort: language filtering should not be fatal.","Flush mangadex:access-token when auth errors appear repeatedly.","Monitor the /settings endpoint independently if language filtering is critical."],"tags":["mangadex","api","authentication","network"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}