{"record":{"id":"83b563730234accd","repo":"DIYgod/RSSHub","slug":"failed-to-retrieve-user-follows-from-mangadex-api","errorCode":null,"errorMessage":"Failed to retrieve user follows from MangaDex API.","messagePattern":"Failed to retrieve user follows from MangaDex API\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/mangadex/mdlist/feed.ts","lineNumber":95,"sourceCode":"\n    const { listName, listAuthor } = (await cache.tryGet(\n        `mangadex:mdlist-info-${id}`,\n        async () => {\n            const response = await got.get(\n                `${constants.API.BASE}/list/${id}${toQueryString({\n                    includes: ['user'],\n                })}`,\n                {\n                    headers: {\n                        Authorization: isPrivate ? `Bearer ${accessToken}` : '',\n                        'User-Agent': config.trueUA,\n                    },\n                }\n            );\n\n            const mdlistInfo = response?.data?.data;\n            if (!mdlistInfo) {\n                throw new Error('Failed to retrieve user follows from MangaDex API.');\n            }\n\n            const listName = mdlistInfo.attributes.name;\n            const listAuthor = mdlistInfo.relationships.find((relationship) => relationship.type === 'user')?.attributes.username;\n\n            return { listName, listAuthor };\n        },\n        config.cache.contentExpire\n    )) as Record<string, any>;\n\n    const feed = (await cache.tryGet(\n        `mangadex:mdlist-feed-${id}`,\n        async () => {\n            const response = await got.get(\n                `${constants.API.BASE}/list/${id}/feed${toQueryString({\n                    limit,\n                    translatedLanguage: languagesQuery,\n                    order: {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mangadex/mdlist/feed.ts#L77-L113","documentation":"Thrown when fetching a MangaDex custom-list's info (GET /list/<id> with includes=user) returns no data.data, used to resolve the list name and author. Cached under mangadex:mdlist-info-<id> for the content-expire duration. Requires a Bearer token when the list is private.","triggerScenarios":"GET https://api.mangadex.org/list/<id>?includes=user where the list id is wrong/deleted, the list is private and no/invalid access token was supplied (Authorization sent only when isPrivate is true), or the API returned an error body.","commonSituations":"User passed a non-existent list id; list was deleted or made private after subscription; MANGADEX auth not configured so private lists return empty; transient API error cached for contentExpire.","solutions":["Open https://api.mangadex.org/list/<id> to confirm the list exists and whether it is private.","If private, configure MANGADEX_* credentials so an access token is sent.","Clear cache key mangadex:mdlist-info-<id> if a transient error was cached.","Verify the list id in the route URL matches the one in the MangaDex UI."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nif (!UUID_RE.test(id)) {\n    throw new Error(`Invalid MangaDex list id: ${id}`);\n}","typeGuard":"const isListInfoResponse = (v: unknown): v is { data: { attributes: { name: string }; relationships: unknown[] } } =>\n    typeof v === 'object' && v !== null && typeof (v as any).data?.attributes?.name === 'string';","tryCatchPattern":"try {\n    info = await getListInfo(id);\n} catch (e) {\n    if (/not found/i.test((e as Error).message)) {\n        return { title: 'List unavailable' }; // degrade the feed\n    }\n    throw e;\n}","preventionTips":["Validate the list id as a UUID at the route boundary.","Configure MANGADEX auth if you subscribe to private lists.","Clear mangadex:mdlist-info-<id> when a list is deleted upstream."],"tags":["mangadex","api","authentication","validation"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}