{"record":{"id":"ca79e0c66a17a346","repo":"DIYgod/RSSHub","slug":"unsupported-model-model","errorCode":null,"errorMessage":"Unsupported model: ${model}","messagePattern":"Unsupported model: (.+?)","errorType":"exception","errorClass":"InvalidParameterError","httpStatus":503,"severity":"warning","filePath":"lib/routes/theinitium/utils.ts","lineNumber":239,"sourceCode":"            break;\n        }\n        case 'tags': {\n            const tagSlug = language ? applyLanguageToTagSlug(type, language) : type;\n            filter = `tag:${tagSlug}`;\n            listLink = `https://theinitium.com/tag/${type}/`;\n            feedName = type;\n            break;\n        }\n        case 'author': {\n            // Author slugs also have -zh-hans suffixed versions for simplified Chinese\n            const authorSlug = language === 'zh-hans' ? `${type}-zh-hans` : type;\n            filter = `author:${authorSlug}`;\n            listLink = `https://theinitium.com/author/${type}/`;\n            feedName = type;\n            break;\n        }\n        default:\n            throw new InvalidParameterError(`Unsupported model: ${model}`);\n    }\n\n    const cacheKey = `theinitium:ghost:${model}:${type}:${language}`;\n    // Use routeExpire (5 min default) and refresh=false so cache actually expires\n    const data = (await cache.tryGet(\n        cacheKey,\n        async () => {\n            const params: Record<string, string> = {\n                include: 'tags,authors',\n                limit: '20',\n            };\n            if (filter) {\n                params.filter = filter;\n            }\n            return await ghostFetch('posts', params);\n        },\n        config.cache.routeExpire,\n        false","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/theinitium/utils.ts#L221-L257","documentation":"processFeed dispatches on a model string ('channel', 'tags', 'author') via a switch. The default branch throws InvalidParameterError for any other model value. This is an internal routing error: model comes from the route definition, not (usually) directly from user input, so an unsupported model means a route was wired to processFeed with an unhandled model.","triggerScenarios":"A theinitium route registers with a model not in {channel, tags, author} (e.g. 'topic' or 'section') and routes to processFeed; the switch falls through to default.","commonSituations":"Adding a new subscription type and forgetting to add its case to the switch; refactoring route definitions and changing the model string; copy-paste route wiring that passes a wrong literal.","solutions":["Add a case in processFeed's switch for the new model, or route the new subscription through an existing model.","Ensure every route that calls processFeed passes one of the supported model literals.","Make the model a union type (type Model = 'channel'|'tags'|'author') so TypeScript flags invalid callers at compile time."],"exampleFix":"// before\nswitch (model) {\n    case 'channel': ...\n    case 'tags': ...\n    case 'author': ...\n    default: throw new InvalidParameterError(`Unsupported model: ${model}`);\n}\n\n// after: narrow with a union type so invalid models are a compile error\ntype FeedModel = 'channel' | 'tags' | 'author';\nexport const processFeed = async (model: FeedModel, ctx: Context) => {\n    switch (model) {\n        case 'channel': ...\n        case 'tags': ...\n        case 'author': ...\n    }\n};","handlingStrategy":"type-guard","validationCode":"type FeedModel = 'channel' | 'tags' | 'author';\nconst SUPPORTED_MODELS = new Set<FeedModel>(['channel', 'tags', 'author']);\nfunction isFeedModel(m: string): m is FeedModel {\n    return SUPPORTED_MODELS.has(m as FeedModel);\n}\n// only call processFeed when isFeedModel(model)","typeGuard":"function isFeedModel(m: string): m is 'channel' | 'tags' | 'author' {\n    return m === 'channel' || m === 'tags' || m === 'author';\n}","tryCatchPattern":"try {\n    return await processFeed(model, ctx);\n} catch (e) {\n    if (e instanceof InvalidParameterError && /Unsupported model/.test(e.message)) {\n        // this is a programmer error; surface it loudly in logs\n        throw new Error(`Route wired to processFeed with bad model \"${model}\"`);\n    }\n    throw e;\n}","preventionTips":["Model is internal: type it as a union so invalid callers fail at compile time.","Add a switch case whenever a new subscription type is introduced.","Audit route definitions that call processFeed to ensure they pass a supported model."],"tags":["validation","parameter","typescript","theinitium"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}