{"record":{"id":"45781f9c147ef255","repo":"jackwener/OpenCLI","slug":"max-content-must-be-a-non-negative-integer-0","errorCode":null,"errorMessage":"--max-content must be a non-negative integer (0 = no cap, full content)","messagePattern":"--max-content must be a non-negative integer \\(0 = no cap, full content\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/answer-detail.js","lineNumber":54,"sourceCode":"    ],\n    columns: ['id', 'author', 'votes', 'comments', 'question_id', 'question_title', 'url', 'created_at', 'updated_at', 'content'],\n    func: async (page, kwargs) => {\n        const target = parseAnswerTarget(kwargs.id);\n        if (!target) {\n            throw new ArgumentError(\n                'Answer ID must be a numeric id, a Zhihu answer URL, or answer:<qid>:<aid>',\n                'Example: opencli zhihu answer-detail 1937205528846655537',\n            );\n        }\n        const { answerId } = target;\n        // `--max-content 0` (the default) means \"no cap, return the\n        // full stripped answer\". Any positive value is an opt-in user\n        // cap, mirroring the wikipedia `page` pattern — we never\n        // silently truncate behind the user's back.\n        const rawMaxContent = kwargs['max-content'];\n        const maxContent = rawMaxContent == null ? 0 : Number(rawMaxContent);\n        if (!Number.isInteger(maxContent) || maxContent < 0) {\n            throw new ArgumentError(\n                '--max-content must be a non-negative integer (0 = no cap, full content)',\n                'Example: --max-content 2000',\n            );\n        }\n        // Navigate to the answer page itself: this both seeds the\n        // cookie/anti-bot context and works even when the caller did\n        // not supply the parent question id (Zhihu redirects from\n        // `/answer/<aid>` to the canonical `/question/<qid>/answer/<aid>`).\n        try {\n            await page.goto(`https://www.zhihu.com/answer/${answerId}`);\n        } catch (err) {\n            throw new CommandExecutionError(\n                `Failed to open Zhihu answer ${answerId}: ${err instanceof Error ? err.message : String(err)}`,\n                'Open the answer URL in Chrome and retry after the page is reachable.',\n            );\n        }\n        const currentQuestionId = page.getCurrentUrl\n            ? extractQuestionIdFromAnswerUrl(await page.getCurrentUrl().catch(() => ''))","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/answer-detail.js#L36-L72","documentation":"This ArgumentError is thrown during argument validation of the zhihu answer-detail command when the --max-content option is provided but is not a non-negative integer. 0 means no cap (full stripped answer is returned); any positive value is an explicit user cap on content length, mirroring the wikipedia `page` pattern so the tool never silently truncates. Non-integers (e.g. 'abc', 1.5) and negative numbers are rejected outright.","triggerScenarios":"Running `clis zhihu answer-detail --max-content -1` (negative), `--max-content 2.5` (non-integer), or `--max-content abc` (non-numeric string), i.e. any value where Number.isInteger(maxContent) is false or maxContent < 0 after Number(rawMaxContent) coercion.","commonSituations":"Typo in the CLI flag value, copy-pasting a value with a units suffix like '2000ch', shell scripts interpolating an empty or negative default (e.g. MAX=-1), or assuming the flag accepts floats for partial caps.","solutions":["Pass a plain non-negative integer, e.g. --max-content 2000, or omit the flag entirely for full content (0 = no cap).","Validate/normalize the value before invoking: Math.trunc a float and clamp negatives to 0.","If the value comes from a script/env var, ensure it is an unquoted digit string without units or sign."],"exampleFix":"// before\nclis zhihu answer-detail --max-content -1\n// after\nclis zhihu answer-detail --max-content 2000","handlingStrategy":"validation","validationCode":"const raw = process.argv.maxContent;\nconst n = raw == null ? 0 : Number(raw);\nif (!Number.isInteger(n) || n < 0) throw new Error('--max-content must be a non-negative integer (0 = no cap)');","typeGuard":"function isValidMaxContent(v) { const n = v == null ? 0 : Number(v); return Number.isInteger(n) && n >= 0; }","tryCatchPattern":"try {\n  await answerDetail({ 'max-content': raw });\n} catch (err) {\n  if (err instanceof ArgumentError) {\n    console.error(`Bad --max-content: ${err.message}`);\n    process.exitCode = 2;\n  } else throw err;\n}","preventionTips":["Omit the flag when you want full content instead of passing 0 or a sentinel.","Clamp/normalize values in wrapper scripts: Math.max(0, Math.trunc(Number(v))).","Never pass floats, negatives, or strings with unit suffixes."],"tags":["argument-validation","cli","input-validation"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}