{"record":{"id":"3ab3768c536b3a02","repo":"DIYgod/RSSHub","slug":"not-found-type-in-id-currenturl","errorCode":null,"errorMessage":"Not found ${type} in ${id}: ${currentUrl}","messagePattern":"Not found (.+?) in (.+?): (.+?)","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"warning","filePath":"lib/routes/aisixiang/thinktank.ts","lineNumber":47,"sourceCode":"async function handler(ctx) {\n    const { id, type = '' } = ctx.req.param();\n    const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30;\n\n    const currentUrl = new URL(`thinktank/${id}.html`, rootUrl).href;\n\n    const { data: response } = await got(currentUrl);\n\n    const $ = load(response);\n\n    const title = `${$('h2').first().text()}${type}`;\n\n    let items: any[] = [];\n\n    const targetList = $('h3')\n        .toArray()\n        .filter((h) => (type ? $(h).text() === type : true));\n    if (!targetList) {\n        throw new InvalidParameterError(`Not found ${type} in ${id}: ${currentUrl}`);\n    }\n\n    for (const l of targetList) {\n        items = [...items, ...$(l).parent().find('ul li a').toArray()];\n    }\n\n    items = items.slice(0, limit).map((item) => {\n        const $item = $(item);\n\n        return {\n            title: $item.text().split('：').pop(),\n            link: new URL($item.prop('href')!, rootUrl).href,\n        };\n    });\n\n    return {\n        item: await ProcessFeed(limit, items),\n        title: `爱思想 - ${title}`,","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/aisixiang/thinktank.ts#L29-L65","documentation":"The aisixiang thinktank page lists an expert's sections under <h3> headers; the route filters those h3s by exact text match against the requested `type`. If nothing matches it intends to throw InvalidParameterError. IMPORTANT BUG: `$('h3').toArray().filter(...)` always returns an Array, and `!targetList` is therefore always FALSE — so this error is effectively dead code and you will get an empty feed instead. The guard almost never fires.","triggerScenarios":"Calling /aisixiang/thinktank/:id/:type where `type` does not exactly match any <h3> text (whitespace, case, or full-width characters differ). Due to the array-truthiness bug, you get an empty feed rather than this error.","commonSituations":"Type label copied with trailing spaces; full-width vs half-width chars; expert reorganised their sections; relying on this throw for user-facing validation that never arrives.","solutions":["Match the exact <h3> text from the expert's page (watch for full-width punctuation and trailing whitespace).","Omit `type` to receive all sections for the expert.","As a maintainer, fix the dead guard: change `if (!targetList)` to `if (!targetList.length)` so the error actually fires."],"exampleFix":"// before (bug — never throws)\nconst targetList = $('h3').toArray().filter((h) => (type ? $(h).text() === type : true));\nif (!targetList) {\n    throw new InvalidParameterError(`Not found ${type} in ${id}: ${currentUrl}`);\n}\n// after\nconst targetList = $('h3').toArray().filter((h) => (type ? $(h).text() === type : true));\nif (targetList.length === 0) {\n    throw new InvalidParameterError(`Not found ${type} in ${id}: ${currentUrl}`);\n}","handlingStrategy":"validation","validationCode":"// NOTE: the in-route guard is buggy (!targetList on an Array is always false),\n// so pre-validate against the actual <h3> texts yourself:\nfunction typeMatchesAnyH3(type, h3Texts) {\n  return h3Texts.some((t) => t.trim() === String(type).trim());\n}","typeGuard":"function isKnownThinktankSection(type, sections): boolean {\n  return sections.includes(String(type).trim());\n}","tryCatchPattern":"// Because the route's guard is dead code, you'll get an empty feed, not a throw.\n// Validate before calling and treat empty results as the real signal:\nconst feed = await fetchAisixiang(id, type);\nif (feed.items.length === 0 && type) {\n  // type didn't match any <h3>; retry without type to get all sections\n  return await fetchAisixiang(id, undefined);\n}","preventionTips":["Remember the in-route guard never fires (Array is always truthy) — pre-validate yourself.","Trim and normalise full-width characters when comparing the type to <h3> text.","If maintaining the route, fix `if (!targetList)` → `if (!targetList.length)` so the contract holds."],"tags":["validation","bug","dead-code","upstream-dependent","rsshub"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}