{"record":{"id":"ddf2acc75cd89560","repo":"jackwener/OpenCLI","slug":"weixin-search-name-is-out-of-range","errorCode":null,"errorMessage":"weixin search --${name} is out of range","messagePattern":"weixin search --(.+?) is out of range","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/weixin/search.js","lineNumber":18,"sourceCode":"import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\n\nconst SOGOU_WEIXIN_DOMAIN = 'weixin.sogou.com';\nconst DEFAULT_PAGE = 1;\nconst DEFAULT_LIMIT = 10;\nconst MAX_LIMIT = 10;\n\nfunction normalizePositiveInteger(value, name, defaultValue, maxValue) {\n    if (value === undefined || value === null)\n        return defaultValue;\n    const text = String(value).trim();\n    if (!/^\\d+$/.test(text)) {\n        throw new ArgumentError(`weixin search --${name} must be a positive integer`, `Pass --${name} as a whole number${maxValue ? ` from 1 to ${maxValue}` : ' greater than 0'}.`);\n    }\n    const parsed = Number(text);\n    if (!Number.isSafeInteger(parsed) || parsed < 1 || (maxValue && parsed > maxValue)) {\n        throw new ArgumentError(`weixin search --${name} is out of range`, `Pass --${name} as a whole number${maxValue ? ` from 1 to ${maxValue}` : ' greater than 0'}.`);\n    }\n    return parsed;\n}\n\nfunction normalizePage(page) {\n    return normalizePositiveInteger(page, 'page', DEFAULT_PAGE);\n}\n\nfunction normalizeLimit(limit) {\n    return normalizePositiveInteger(limit, 'limit', DEFAULT_LIMIT, MAX_LIMIT);\n}\n\nfunction buildSearchUrl(query, pageNo) {\n    const searchUrl = new URL('https://weixin.sogou.com/weixin');\n    searchUrl.searchParams.set('query', query);\n    searchUrl.searchParams.set('type', '2');\n    searchUrl.searchParams.set('page', String(pageNo));\n    searchUrl.searchParams.set('ie', 'utf8');","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/search.js#L1-L36","documentation":"After passing the digit-format test, `normalizePositiveInteger` checks that the parsed value is a safe integer, >= 1, and (when a maxValue is given) <= maxValue. If any check fails it throws ArgumentError with message 'weixin search --<name> is out of range', hinting the accepted range. This prevents nonsensical pages (0 or negative overflow like 00000) and limits beyond the backend's maximum. Exit code is 2 (usage error).","triggerScenarios":"Calling `opencli weixin search` with --page 0, --limit 0, an astronomically large value exceeding Number.isSafeInteger bounds (e.g. '99999999999999999999'), or --limit above the maxValue configured for the command.","commonSituations":"Users trying --page 0 expecting 1-indexed-vs-0-indexed confusion; scripts computing limits that overflow; passing sentinel values like 999999 to mean 'everything'; copy-pasted oversized numbers.","solutions":["Use --page >= 1 and --limit >= 1 within the command's documented maximum","Clamp or cap the value in your script before invoking the CLI","If you want 'as many as possible', omit --limit to get the built-in default instead of a huge number"],"exampleFix":"// before\nopencli weixin search \"golang\" --limit 999999999999999999999  // out of range\n// after\nconst limit = Math.min(Math.max(1, Number(userLimit) || 10), 50);\nopencli weixin search \"golang\" --limit limit","handlingStrategy":"validation","validationCode":"function clampInt(v, min, max, fallback) {\n  if (v === undefined || v === null) return fallback;\n  const n = Number(String(v).trim());\n  if (!Number.isSafeInteger(n)) return fallback;\n  return Math.min(Math.max(n, min), max);\n}\nconst page = clampInt(rawPage, 1, undefined, 1);\nconst limit = clampInt(rawLimit, 1, 50, 10);","typeGuard":"function isInRangePositiveInt(v, maxValue) {\n  if (!/^\\d+$/.test(String(v).trim())) return false;\n  const n = Number(v);\n  return Number.isSafeInteger(n) && n >= 1 && (!maxValue || n <= maxValue);\n}","tryCatchPattern":"try {\n  await run(['weixin', 'search', q, '--page', String(page)]);\n} catch (e) {\n  if (e instanceof CliError && e.code === 'ARGUMENT' && e.message.includes('out of range')) {\n    // retry with clamped values\n    await run(['weixin', 'search', q, '--page', '1', '--limit', '10']);\n  } else throw e;\n}","preventionTips":["Clamp page/limit to >= 1 and any documented maximum before invoking the CLI","Omit --limit/--page to use the command defaults instead of sentinel huge values","Never use 0 or negative numbers as page values (the API is 1-indexed)","Guard computed values with Number.isSafeInteger before serializing them into flags"],"tags":["argument-validation","cli-usage","weixin"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}