{"record":{"id":"24369540daca803f","repo":"jackwener/OpenCLI","slug":"invalid-argument-243695","errorCode":"INVALID_ARGUMENT","errorMessage":"INVALID_ARGUMENT","messagePattern":"INVALID_ARGUMENT","errorType":"error_code","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"clis/xiaoyuzhou/podcast-episodes.js","lineNumber":21,"sourceCode":"import { loadXiaoyuzhouCredentials, requestXiaoyuzhouJson } from './auth.js';\nimport { formatDuration, formatDate } from './utils.js';\ncli({\n    site: 'xiaoyuzhou',\n    name: 'podcast-episodes',\n    access: 'read',\n    description: 'List episodes of a Xiaoyuzhou podcast',\n    domain: 'www.xiaoyuzhoufm.com',\n    strategy: Strategy.LOCAL,\n    browser: false,\n    args: [\n        { name: 'id', positional: true, required: true, help: 'Podcast ID (from xiaoyuzhoufm.com URL)' },\n        { name: 'limit', type: 'int', default: 20, help: 'Max episodes to show' },\n    ],\n    columns: ['eid', 'title', 'duration', 'plays', 'date'],\n    func: async (args) => {\n        const requestedLimit = Number(args.limit);\n        if (!Number.isInteger(requestedLimit) || requestedLimit < 1) {\n            throw new CliError('INVALID_ARGUMENT', 'limit must be a positive integer', 'Example: --limit 5');\n        }\n        const credentials = loadXiaoyuzhouCredentials();\n        const response = await requestXiaoyuzhouJson('/v1/episode/list', {\n            method: 'POST',\n            body: { pid: args.id, order: 'desc', limit: requestedLimit },\n            credentials,\n        });\n        const episodes = response.data ?? [];\n        if (!Array.isArray(episodes)) {\n            throw new CliError('PARSE_ERROR', 'Unexpected API response format', 'Expected an array of episodes');\n        }\n        return episodes.map((ep) => ({\n            eid: ep.eid,\n            title: ep.title,\n            duration: formatDuration(ep.duration),\n            plays: ep.playCount,\n            date: formatDate(ep.pubDate),\n        }));","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoyuzhou/podcast-episodes.js#L3-L39","documentation":"The xiaoyuzhou podcast-episodes CLI validates the --limit argument before calling the API. If it is not a positive integer (e.g. 0, negative, or non-numeric like 'abc'), the CLI throws a CliError with code INVALID_ARGUMENT instead of sending a bad request upstream. It exists to fail fast with an actionable example in the hint.","triggerScenarios":"Calling `opencli xiaoyuzhou podcast-episodes <id>` with `--limit 0`, a negative number, a non-integer float like `--limit 2.5`, or a non-numeric string such as `--limit ten`; the check `Number.isInteger(requestedLimit) && requestedLimit >= 1` fails.","commonSituations":"Copy-pasting flag values with stray whitespace or units ('20 eps'), scripting loops that compute limit as 0 for an empty batch, shell quoting issues producing empty strings, or confusing limit with an offset.","solutions":["Pass a positive integer, e.g. `--limit 5`","Check the value being passed in your script is a whole number >= 1","If computing the limit dynamically, clamp it: Math.max(1, Math.floor(n))","Omit --limit to use the default of 20"],"exampleFix":"// before\nopencli xiaoyuzhou podcast-episodes <pid> --limit 0\n// after\nopencli xiaoyuzhou podcast-episodes <pid> --limit 20","handlingStrategy":"validation","validationCode":"function isValidLimit(v){ const n = Number(v); return Number.isInteger(n) && n >= 1; }\nif (!isValidLimit(opts.limit)) throw new Error('--limit must be a positive integer');","typeGuard":"const isPositiveInt = (v) => Number.isInteger(Number(v)) && Number(v) >= 1;","tryCatchPattern":"try { await run(['opencli','xiaoyuzhou','podcast-episodes',id,'--limit',limit]); } catch (e) { if (String(e).includes('INVALID_ARGUMENT')) { console.error('Fix --limit, must be positive integer'); process.exitCode = 2; } else throw e; }","preventionTips":["Validate numeric flags with Number.isInteger before passing them","Clamp computed values: Math.max(1, Math.floor(n))","Let the flag default (20) apply instead of passing values blindly","Watch for shell stringification of numbers"],"tags":["cli","argument-validation","input-validation"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}