{"record":{"id":"5850966d13bb8f7b","repo":"DIYgod/RSSHub","slug":"data-errors-0-detail","errorCode":null,"errorMessage":"${data.errors[0].detail}","messagePattern":"\\$\\{data\\.errors\\[0\\]\\.detail\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/mangadex/_feed.ts","lineNumber":30,"sourceCode":" *\n * @author chrisis58, vzz64\n * @param id manga id\n * @param lang language(s), absent for default\n * @param needCover whether to fetch cover\n * @returns title, description, and cover of the manga\n */\nconst getMangaMeta = async (id: string, needCover: boolean = true, lang?: string | string[]) => {\n    const includes = needCover ? ['cover_art'] : [];\n\n    const rawMangaMeta = (await cache.tryGet(`mangadex:manga-meta:${id}`, async () => {\n        const { data } = await got.get(\n            `${constants.API.MANGA_META}${id}${toQueryString({\n                includes,\n            })}`\n        );\n\n        if (data.result === 'error') {\n            throw new Error(data.errors[0].detail);\n        }\n        return data.data;\n    })) as any;\n\n    const relationships = (rawMangaMeta.relationships || []) as Array<{ type: string; id: string; attributes: any }>;\n\n    const languages = [\n        ...(typeof lang === 'string' ? [lang] : lang || []),\n        ...(await getFilteredLanguages()),\n        rawMangaMeta.attributes.originalLanguage, // fallback to original language\n    ].filter(Boolean);\n\n    // combine title and altTitles\n    const titles = {\n        ...rawMangaMeta.attributes.title,\n        ...Object.fromEntries(rawMangaMeta.attributes.altTitles.flatMap((element) => Object.entries(element))),\n    };\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mangadex/_feed.ts#L12-L48","documentation":"Re-throws the MangaDex API's own error detail when fetching a single manga's metadata (GET /manga/:id). The handler checks data.result === 'error' and surfaces data.errors[0].detail verbatim, so the actual message is whatever MangaDex returned (e.g. 'Manga not found', rate-limit detail). It is cached under mangadex:manga-meta:<id>.","triggerScenarios":"GET https://api.mangadex.org/manga/<id>?includes[]=cover_art where <id> is not a valid manga UUID, refers to a deleted/restricted manga, or the request was rate-limited (429 returned in-body).","commonSituations":"User passed a malformed or non-UUID manga id in the route; manga was deleted/taken down; RSSHub IP temporarily rate-limited by MangaDex; downstream route handed a chapter/group id where a manga id was expected.","solutions":["Validate the manga id is a UUID and exists by opening https://api.mangadex.org/manga/<id> in a browser.","If rate-limited, wait and let the cache entry (mangadex:manga-meta:<id>) expire before retrying.","Surface a clearer error by wrapping: catch and re-throw with the requested id included.","If the manga was deleted, remove the subscription feeding this id."],"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;\nfunction validateMangaId(id: string) {\n    if (!UUID_RE.test(id)) {\n        throw new Error(`Invalid MangaDex manga id: ${id}`);\n    }\n}","typeGuard":"interface MangadexErrorResponse {\n    result: 'ok' | 'error';\n    errors?: Array<{ detail: string }>;\n}\nconst isMangadexErrorBody = (v: unknown): v is MangadexErrorResponse =>\n    typeof v === 'object' && v !== null && (v as { result?: string }).result === 'error';","tryCatchPattern":"try {\n    meta = await getMangaMeta(id);\n} catch (e) {\n    if (/not found/i.test((e as Error).message)) {\n        // drop the bad id from the source list rather than failing the whole feed\n        continue;\n    }\n    throw e;\n}","preventionTips":["Validate manga ids as UUIDs at the route boundary.","Cache positive results so a transient API error does not repeat on every poll.","When surfacing the error, include the requested id for debuggability."],"tags":["mangadex","api","validation","network"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}