{"record":{"id":"4e86810d54f500d3","repo":"jackwener/OpenCLI","slug":"weread-official-type-must-be-one-of-object-key","errorCode":null,"errorMessage":"weread-official: type must be one of: ${Object.keys(TYPE_ALIASES).join(', ')}","messagePattern":"weread-official: type must be one of: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/weread-official/review.js","lineNumber":52,"sourceCode":"    name: 'review',\n    access: 'read',\n    description: 'Browse public reviews of a WeRead book',\n    domain: 'weread.qq.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'bookId', positional: true, required: true, help: 'WeRead bookId (from `weread-official search`)' },\n        { name: 'type', default: 'all', choices: Object.keys(TYPE_ALIASES), help: 'Review filter (all/recommend/thumbs-down/newest/neutral)' },\n        { name: 'count', type: 'int', default: 20, help: 'Page size (1-100, default 20)' },\n        { name: 'max-idx', type: 'int', default: 0, help: 'Pagination cursor — pass idx from last row of previous page' },\n        { name: 'synckey', type: 'int', help: 'Sync cursor returned by previous response' },\n    ],\n    columns: ['rank', 'idx', 'reviewId', 'star', 'starLabel', 'author', 'isFinish', 'chapter', 'content', 'createTime', 'link'],\n    func: async (args) => {\n        const bookId = requireBookId(args.bookId);\n        const typeKey = String(args.type ?? 'all').trim();\n        if (!Object.prototype.hasOwnProperty.call(TYPE_ALIASES, typeKey)) {\n            throw new ArgumentError(\n                `weread-official: type must be one of: ${Object.keys(TYPE_ALIASES).join(', ')}`,\n            );\n        }\n        const reviewListType = TYPE_ALIASES[typeKey];\n        const count = requirePositiveInt(args.count, 'count', { defaultValue: 20, max: 100 });\n        const params = { bookId, reviewListType, count, maxIdx: Number(args['max-idx'] ?? 0) };\n        if (args.synckey !== undefined && args.synckey !== null && args.synckey !== '') {\n            params.synckey = requirePositiveInt(args.synckey, 'synckey');\n        }\n\n        const payload = await callGateway('/review/list', params);\n        const reviews = Array.isArray(payload?.reviews) ? payload.reviews : [];\n        if (reviews.length === 0) {\n            emptyResult('review', `No public reviews for bookId=${bookId} (type=${typeKey}).`);\n        }\n\n        return reviews.map((wrapper, i) => {\n            const reviewOuter = wrapper?.review ?? {};","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread-official/review.js#L34-L70","documentation":"This ArgumentError is thrown by `weread-official review` when the `type` argument is not one of the keys of TYPE_ALIASES (validated via hasOwnProperty). The alias map converts the user-facing type into the API's reviewListType parameter. It is a strict enum-validation error raised before any API call.","triggerScenarios":"Passing `--type` with a value not in the allowed alias keys (e.g. typo like 'reviw', unsupported like 'like', or wrong casing since the check is case-sensitive and the key is trimmed but not lowercased).","commonSituations":"Guessing type names without checking --help; migrating from another weread tool that used different type vocabularies; scripting with a variable containing an unexpected value; capitalization differences like 'All' vs 'all'.","solutions":["Run the command with --help or check TYPE_ALIASES for the exact accepted keys","Match the case exactly (the lookup is case-sensitive)","Default is 'all' — omit --type to get all reviews","Normalize your input with .toLowerCase() before passing if the aliases are lowercase"],"exampleFix":"// before\nawait wereadReview({ bookId, type: 'Latest' });\n// after\nconst allowed = ['all', 'hot', 'latest']; // see TYPE_ALIASES\nconst t = String(type).trim().toLowerCase();\nif (!allowed.includes(t)) throw new Error(`type must be one of ${allowed.join(', ')}`);\nawait wereadReview({ bookId, type: t });","handlingStrategy":"validation","validationCode":"const TYPE_KEYS = ['all','hot','latest']; // mirror TYPE_ALIASES\nif (!TYPE_KEYS.includes(String(type ?? 'all').trim())) throw new Error(`type must be one of: ${TYPE_KEYS.join(', ')}`);","typeGuard":"function isValidReviewType(t) { return typeof t === 'string' && Object.keys(TYPE_ALIASES).includes(t.trim()); }","tryCatchPattern":"try { await wereadReview(args); }\ncatch (e) { if (e.name === 'ArgumentError' && e.message.includes('type must be')) { printAllowedTypes(); } else throw e; }","preventionTips":["Omit --type to use the 'all' default","Copy type values from --help, not memory","Lowercase/normalize inputs before passing"],"tags":["argument-validation","enum","cli"],"backgroundTag":"invalid-enum-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}