{"record":{"id":"78c642cb564f8956","repo":"jackwener/OpenCLI","slug":"invalid-argument-78c642","errorCode":"INVALID_ARGUMENT","errorMessage":"--limit must be a positive integer no greater than 100","messagePattern":"--limit must be a positive integer no greater than 100","errorType":"validation","errorClass":"CliError","httpStatus":null,"severity":"warning","filePath":"clis/ths/hot-rank.js","lineNumber":17,"sourceCode":"import { cli, Strategy } from '@jackwener/opencli/registry';\nimport { CliError } from '@jackwener/opencli/errors';\n\nconst THS_HOT_API_URL = 'https://dq.10jqka.com.cn/fuyao/hot_list_data/out/hot_list/v1/stock?stock_type=a&type=hour&list_type=normal';\n\nfunction tagsFromStock(stock) {\n  const tag = stock?.tag && typeof stock.tag === 'object' ? stock.tag : {};\n  return [\n    ...(Array.isArray(tag.concept_tag) ? tag.concept_tag : []),\n    ...(Array.isArray(tag.popularity_tag) ? tag.popularity_tag : []),\n  ].filter(Boolean).join(',');\n}\n\nfunction parseLimit(raw) {\n  const limit = Number(raw ?? 20);\n  if (!Number.isInteger(limit) || limit <= 0 || limit > 100) {\n    throw new CliError('INVALID_ARGUMENT', '--limit must be a positive integer no greater than 100');\n  }\n  return limit;\n}\n\ncli({\n  site: 'ths',\n  name: 'hot-rank',\n    access: 'read',\n  description: '同花顺热股榜',\n  domain: 'dq.10jqka.com.cn',\n  strategy: Strategy.PUBLIC,\n  browser: false,\n  args: [\n    { name: 'limit', type: 'int', default: 20, help: '返回数量' },\n  ],\n  columns: ['rank', 'name', 'changePercent', 'heat', 'tags'],\n  func: async (args) => {\n    const limit = parseLimit(args.limit);","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ths/hot-rank.js#L1-L35","documentation":"parseLimit validates the --limit option for the ths hot-rank CLI. It must be an integer in 1..100 (defaulting to 20); anything else throws CliError with code INVALID_ARGUMENT. This fails fast on bad user input before any network call.","triggerScenarios":"Passing --limit as 0, negative, >100, or a non-integer/non-numeric string (e.g. 'abc', '2.5', '0', '101'). Number(raw ?? 20) coerces, so '' becomes 0 and 'all' becomes NaN — both invalid.","commonSituations":"User typos a value over the API cap (ths rank API returns at most ~100 rows); passing '10%' or 'top10'; shell scripts interpolating empty variables.","solutions":["Pass an integer between 1 and 100, e.g. --limit 50","Omit --limit entirely to use the default of 20","Quote/validate the value in shell scripts before interpolation","Clamp user-supplied input in your wrapper before invoking the CLI"],"exampleFix":"// before\nths hot-rank --limit 250\n// after\nths hot-rank --limit 100","handlingStrategy":"validation","validationCode":"function coerceLimit(raw, { min = 1, max = 100, dflt = 20 } = {}) {\n  const n = Number(raw ?? dflt);\n  if (!Number.isInteger(n) || n < min || n > max) return dflt;\n  return n;\n}\nconst limit = coerceLimit(process.env.LIMIT ?? cliArgs.limit);","typeGuard":"function isValidLimit(v) {\n  return Number.isInteger(v) && v > 0 && v <= 100;\n}","tryCatchPattern":"try {\n  await thsHotRank({ limit });\n} catch (e) {\n  if (e?.code === 'INVALID_ARGUMENT') {\n    console.error('Usage: --limit <1-100 integer>');\n    process.exitCode = 2;\n    return;\n  }\n  throw e;\n}","preventionTips":["Clamp user input: Math.min(100, Math.max(1, n)) before passing --limit","Omit --limit to use the default 20","Validate interpolated shell variables are non-empty integers","Document the 1..100 cap in your wrapper's help text"],"tags":["cli","validation","argument-error","ths"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}