{"record":{"id":"180d6bb85a3f9abd","repo":"jackwener/OpenCLI","slug":"invalid-argument-180d6b","errorCode":"INVALID_ARGUMENT","errorMessage":"Unknown period \"${periodKey}\". Valid: ${Object.keys(PERIOD_MAP).join(', ')}","messagePattern":"Unknown period \"(.+?)\"\\. Valid: (.+?)","errorType":"error_code","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"clis/eastmoney/kline.js","lineNumber":45,"sourceCode":"  name: 'kline',\n    access: 'read',\n  description: 'K线历史数据（分/日/周/月/前复权/后复权）',\n  domain: 'push2his.eastmoney.com',\n  strategy: Strategy.PUBLIC,\n  browser: false,\n  args: [\n    { name: 'symbol', required: true, positional: true, help: '股票代码（A/HK/US 均可）' },\n    { name: 'period', type: 'string', default: 'day', help: '周期：1m/5m/15m/30m/60m/day/week/month' },\n    { name: 'adjust', type: 'string', default: 'forward', help: '复权：none / forward / backward' },\n    { name: 'limit',  type: 'int',    default: 30,        help: '返回最近 N 根（末尾）' },\n  ],\n  columns: ['date', 'open', 'close', 'high', 'low', 'volume', 'turnover', 'amplitude', 'changePercent', 'change', 'turnoverRate'],\n  func: async (args) => {\n    const secid = resolveSecid(args.symbol);\n    const periodKey = String(args.period ?? 'day').toLowerCase();\n    const klt = PERIOD_MAP[periodKey];\n    if (klt == null) {\n      throw new CliError('INVALID_ARGUMENT', `Unknown period \"${periodKey}\". Valid: ${Object.keys(PERIOD_MAP).join(', ')}`);\n    }\n    const adjustKey = String(args.adjust ?? 'forward').toLowerCase();\n    const fqt = ADJUST_MAP[adjustKey];\n    if (fqt == null) {\n      throw new CliError('INVALID_ARGUMENT', `Unknown adjust \"${adjustKey}\". Valid: none / forward / backward`);\n    }\n    const limit = Math.max(1, Math.min(Number(args.limit) || 30, 1000));\n\n    const url = new URL('https://push2his.eastmoney.com/api/qt/stock/kline/get');\n    url.searchParams.set('secid', secid);\n    url.searchParams.set('klt', String(klt));\n    url.searchParams.set('fqt', String(fqt));\n    url.searchParams.set('beg', '0');\n    url.searchParams.set('end', '20500101');\n    url.searchParams.set('fields1', 'f1,f2,f3,f4,f5,f6');\n    url.searchParams.set('fields2', 'f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61');\n    url.searchParams.set('ut', 'b2884a393a59ad64002292a3e90d46a5');\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/eastmoney/kline.js#L27-L63","documentation":"This CliError with code INVALID_ARGUMENT is thrown when the period argument does not match any key in PERIOD_MAP. The library lowercases the input then looks up the klt (K-line interval) code; an unknown key means no mapping exists. It fails before any HTTP request is made.","triggerScenarios":"Calling kline with period values like 'daily', '1d', 'weekly', '1h', 'month', or any string not present in PERIOD_MAP keys (e.g. when only day/week/month style keys are supported). Case is handled by toLowerCase, so 'DAY' is fine, but synonyms like 'daily' are not.","commonSituations":"Mapping user-friendly period names ('daily', 'weekly') directly to the API without translating to supported keys; config files written for a different library's period vocabulary; frontend dropdown values drifting from supported PERIOD_MAP keys after a refactor.","solutions":["Use a key that exists in PERIOD_MAP (check the error message, which lists all valid keys)","Normalize synonyms before calling: map 'daily'->'day', 'weekly'->'week', 'monthly'->'month' in your own code","Default explicitly to 'day' when period is absent instead of passing an empty/garbage string","Keep your UI/config period options in sync with the PERIOD_MAP keys"],"exampleFix":"// before\nawait kline({ symbol: '600000', period: 'daily' }) // throws INVALID_ARGUMENT\n// after\nconst SYNONYMS = { daily: 'day', weekly: 'week', monthly: 'month' };\nconst period = SYNONYMS[userPeriod] ?? userPeriod ?? 'day';\nawait kline({ symbol: '600000', period });","handlingStrategy":"validation","validationCode":"const PERIOD_MAP_KEYS = ['day', 'week', 'month']; // mirror PERIOD_MAP keys from the library\nfunction validatePeriod(period) {\n  const p = String(period ?? 'day').toLowerCase();\n  if (!PERIOD_MAP_KEYS.includes(p)) {\n    throw new Error(`Unknown period \"${p}\". Valid: ${PERIOD_MAP_KEYS.join(', ')}`);\n  }\n  return p;\n}","typeGuard":"function isValidPeriod(p) {\n  return typeof p === 'string' && ['day', 'week', 'month'].includes(p.toLowerCase());\n}","tryCatchPattern":"try {\n  return await kline({ symbol, period: validatePeriod(userPeriod) });\n} catch (err) {\n  if (err.code === 'INVALID_ARGUMENT' && err.message.startsWith('Unknown period')) {\n    console.warn(`${err.message} — falling back to 'day'`);\n    return kline({ symbol, period: 'day' });\n  }\n  throw err;\n}","preventionTips":["Keep a synonym map (daily->day, weekly->week, monthly->month) at the boundary of your app","Default to 'day' when period is undefined or empty","Mirror PERIOD_MAP keys in a shared constant so UI options can never drift","Parse the valid-keys list from the error message to surface correct options to users"],"tags":["validation","invalid-argument","cli","kline"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}