{"record":{"id":"58b6c65176a9efda","repo":"jackwener/OpenCLI","slug":"unknown-category-value","errorCode":null,"errorMessage":"Unknown category: ${value}","messagePattern":"Unknown category: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/linux-do/feed.js","lineNumber":255,"sourceCode":"    }));\n}\n/**\n * 解析标签，支持 id、name、slug 三种输入。\n */\nasync function resolveTag(page, value) {\n    const liveTag = findMatchingTag(await fetchLiveTags(page), value);\n    if (liveTag)\n        return liveTag;\n    throw new ArgumentError(`Unknown tag: ${value}`, 'Use \"opencli linux-do tags\" to list available tags');\n}\n/**\n * 解析分类，并补齐父分类信息。\n */\nasync function resolveCategory(page, value) {\n    const liveCategory = findMatchingCategory(await fetchLiveCategories(page), value);\n    if (liveCategory)\n        return liveCategory;\n    throw new ArgumentError(`Unknown category: ${value}`, 'Use \"opencli linux-do categories\" to list available categories');\n}\n/**\n * 将命令参数转换为最终请求地址\n */\nasync function resolveFeedRequest(page, kwargs) {\n    const view = (kwargs.view || 'latest');\n    const period = (kwargs.period || 'weekly');\n    if (kwargs.period && view !== 'top') {\n        throw new ArgumentError('--period is only valid with --view top');\n    }\n    const params = new URLSearchParams();\n    if (kwargs.order && kwargs.order !== 'default')\n        params.set('order', kwargs.order);\n    if (kwargs.ascending)\n        params.set('ascending', 'true');\n    if (kwargs.limit)\n        params.set('per_page', String(kwargs.limit));\n    const tagValue = typeof kwargs.tag === 'string' ? kwargs.tag.trim() : '';","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linux-do/feed.js#L237-L273","documentation":"resolveCategory matches the user-supplied value against live categories fetched from linux.do (by id, name, or slug, with parent info filled in) and throws ArgumentError when nothing matches. The hint points to `opencli linux-do categories` for the valid list. Like resolveTag, this fires only after the category metadata was successfully retrieved, so it is purely an input mismatch.","triggerScenarios":"`opencli linux-do feed --category <value>` where value matches no category id, name, or slug: typo, using a subcategory display name that differs from its slug, referencing a deleted/restructured category, or passing a tag value to --category.","commonSituations":"linux.do reorganized categories so old names no longer resolve; user copies the Chinese display name with different spacing; using the parent name when the child slug is required; stale 24h cache after a forum restructure.","solutions":["Run `opencli linux-do categories` and use the exact id, name, or slug shown","If targeting a subcategory, use its own slug/id rather than the parent's","Delete ~/.opencli/cache/linux-do/categories.json to force a refresh if the forum was recently reorganized","If you meant a tag, use --tag instead of --category"],"exampleFix":"// before (shell)\nopencli linux-do feed --category \"开发调优\"   // Unknown category: 开发调优 (renamed)\n// after (shell)\nopencli linux-do categories               # find current id, e.g. 94\nopencli linux-do feed --category 94","handlingStrategy":"validation","validationCode":"// Validate the category before calling the feed command\nconst categories = await fetchLiveCategories(page);\nfunction isValidCategory(value) {\n    const norm = s => s.trim().replace(/\\s+/g, ' ').toLowerCase();\n    return categories.some(c =>\n        String(c.id) === value.trim() ||\n        norm(c.name) === norm(value) ||\n        norm(c.slug) === norm(value));\n}\nif (!isValidCategory(userValue)) {\n    console.error('Invalid category. Run: opencli linux-do categories');\n    process.exit(1);\n}","typeGuard":"function isKnownCategory(records, value) {\n    const norm = s => String(s).trim().replace(/\\s+/g, ' ').toLowerCase();\n    return records.some(r =>\n        String(r.id) === value.trim() ||\n        norm(r.name) === norm(value) ||\n        norm(r.slug) === norm(value));\n}","tryCatchPattern":"import { ArgumentError } from '@jackwener/opencli/errors';\ntry {\n    await category(value);\n} catch (err) {\n    if (err instanceof ArgumentError && err.message.startsWith('Unknown category:')) {\n        console.error(`${err.message}\\n${err.hint || 'Run: opencli linux-do categories'}`);\n        process.exitCode = 1;\n    } else {\n        throw err;\n    }\n}","preventionTips":["Pick categories from `opencli linux-do categories` output; prefer id or slug","Use the subcategory's own slug, not the parent's name","Refresh the categories cache after forum restructuring (TTL 24h)","Don't pass tag values to --category — they live in separate namespaces"],"tags":["argument-validation","cli","user-input","not-found"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}