{"record":{"id":"85b7fff567297e04","repo":"jackwener/OpenCLI","slug":"invalid-argument-85b7ff","errorCode":"INVALID_ARGUMENT","errorMessage":"At least one symbol is required","messagePattern":"At least one symbol is required","errorType":"validation","errorClass":"CliError","httpStatus":null,"severity":"warning","filePath":"clis/eastmoney/quote.js","lineNumber":64,"sourceCode":"  name: 'quote',\n    access: 'read',\n  description: '个股实时行情（A股 / 港股 / 美股）— 来自 push2.eastmoney.com',\n  domain: 'push2.eastmoney.com',\n  strategy: Strategy.PUBLIC,\n  browser: false,\n  args: [\n    { name: 'symbols', required: true, positional: true, help: '股票代码（可用逗号/空格分隔多个）' },\n  ],\n  columns: [\n    'code', 'name', 'market', 'price', 'changePercent', 'change',\n    'open', 'high', 'low', 'prevClose', 'volume', 'turnover',\n    'turnoverRate', 'amplitude', 'peDynamic', 'priceBook',\n    'marketCap', 'floatMarketCap',\n  ],\n  func: async (args) => {\n    const raw = splitSymbols(args.symbols);\n    if (raw.length === 0) {\n      throw new CliError('INVALID_ARGUMENT', 'At least one symbol is required');\n    }\n\n    /** @type {string[]} */\n    const secids = [];\n    for (const s of raw) {\n      try { secids.push(resolveSecid(s)); }\n      catch (err) { throw new CliError('INVALID_ARGUMENT', `Unrecognized symbol \"${s}\"`); }\n    }\n\n    // Multi-stock in one call via ulist.np\n    const url = new URL('https://push2.eastmoney.com/api/qt/ulist.np/get');\n    url.searchParams.set('secids', secids.join(','));\n    url.searchParams.set('fltt', '2');\n    url.searchParams.set('fields', FIELDS);\n    url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');\n\n    const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0', Accept: 'application/json' } });\n    if (!resp.ok) throw new CliError('HTTP_ERROR', `eastmoney quote failed: HTTP ${resp.status}`);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/eastmoney/quote.js#L46-L82","documentation":"quote.js splits the --symbols argument with splitSymbols() (splitting on commas, Chinese commas, and whitespace) and throws this CliError INVALID_ARGUMENT if nothing remains. The quote command requires at least one stock symbol to build the secid list for the ulist.np request.","triggerScenarios":"Calling `eastmoney quote` with no --symbols value, an empty string, or a value consisting only of separators (e.g. `--symbols=\",\"` or `--symbols=\" \"`) — splitSymbols filters out empty tokens, so raw.length === 0.","commonSituations":"Omitting the --symbols flag entirely; passing an environment/variable that expanded to empty in shell scripts; copy-paste errors that left only delimiters; quoting mistakes that made the shell swallow the value.","solutions":["Pass at least one symbol, e.g. `quote --symbols=600000` or `quote --symbols=AAPL`","In scripts, verify the symbols variable is non-empty before invoking","Separate multiple symbols with commas or spaces: `--symbols=\"600000,00700.HK,AAPL\"`","Check shell quoting so the value is not eaten by the shell"],"exampleFix":"// before\nquote --symbols=\"\"\n// after\nquote --symbols=\"600000,000001\"","handlingStrategy":"validation","validationCode":"const symbols = String(process.env.SYMBOLS || '').trim();\nif (!symbols || !/[\\w.]/.test(symbols)) throw new Error('SYMBOLS must contain at least one ticker, e.g. 600000 or AAPL');\nawait cliQuote({ symbols });","typeGuard":"const hasSymbols = (s) => String(s ?? '').split(/[,，\\s]+/).filter(Boolean).length > 0;","tryCatchPattern":"try {\n  await runQuote(args);\n} catch (e) {\n  if (e.code === 'INVALID_ARGUMENT' && /At least one symbol/.test(e.message)) {\n    console.error('Usage: quote --symbols=\"600000,00700.HK,AAPL\"');\n  } else throw e;\n}","preventionTips":["Always pass --symbols explicitly; never rely on possibly-empty shell variables","Guard script variables: [ -n \"$SYMBOLS\" ] || exit 1 before invoking","Quote the argument so spaces/commas survive shell parsing","Remember commas, Chinese commas, and whitespace all act as separators"],"tags":["cli","argument-validation","invalid-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}