jackwener/OpenCLI · error · CliError
INVALID_ARGUMENT
INVALID_ARGUMENT
Error message
Unknown period "${periodKey}". Valid: ${Object.keys(PERIOD_MAP).join(', ')} What it means
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.
Source
Thrown at clis/eastmoney/kline.js:45
name: 'kline',
access: 'read',
description: 'K线历史数据(分/日/周/月/前复权/后复权)',
domain: 'push2his.eastmoney.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'symbol', required: true, positional: true, help: '股票代码(A/HK/US 均可)' },
{ name: 'period', type: 'string', default: 'day', help: '周期:1m/5m/15m/30m/60m/day/week/month' },
{ name: 'adjust', type: 'string', default: 'forward', help: '复权:none / forward / backward' },
{ name: 'limit', type: 'int', default: 30, help: '返回最近 N 根(末尾)' },
],
columns: ['date', 'open', 'close', 'high', 'low', 'volume', 'turnover', 'amplitude', 'changePercent', 'change', 'turnoverRate'],
func: async (args) => {
const secid = resolveSecid(args.symbol);
const periodKey = String(args.period ?? 'day').toLowerCase();
const klt = PERIOD_MAP[periodKey];
if (klt == null) {
throw new CliError('INVALID_ARGUMENT', `Unknown period "${periodKey}". Valid: ${Object.keys(PERIOD_MAP).join(', ')}`);
}
const adjustKey = String(args.adjust ?? 'forward').toLowerCase();
const fqt = ADJUST_MAP[adjustKey];
if (fqt == null) {
throw new CliError('INVALID_ARGUMENT', `Unknown adjust "${adjustKey}". Valid: none / forward / backward`);
}
const limit = Math.max(1, Math.min(Number(args.limit) || 30, 1000));
const url = new URL('https://push2his.eastmoney.com/api/qt/stock/kline/get');
url.searchParams.set('secid', secid);
url.searchParams.set('klt', String(klt));
url.searchParams.set('fqt', String(fqt));
url.searchParams.set('beg', '0');
url.searchParams.set('end', '20500101');
url.searchParams.set('fields1', 'f1,f2,f3,f4,f5,f6');
url.searchParams.set('fields2', 'f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61');
url.searchParams.set('ut', 'b2884a393a59ad64002292a3e90d46a5');
View on GitHub (pinned to 49907e53dc)
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
Example fix
// before
await kline({ symbol: '600000', period: 'daily' }) // throws INVALID_ARGUMENT
// after
const SYNONYMS = { daily: 'day', weekly: 'week', monthly: 'month' };
const period = SYNONYMS[userPeriod] ?? userPeriod ?? 'day';
await kline({ symbol: '600000', period }); Defensive patterns
Strategy: validation
Validate before calling
const PERIOD_MAP_KEYS = ['day', 'week', 'month']; // mirror PERIOD_MAP keys from the library
function validatePeriod(period) {
const p = String(period ?? 'day').toLowerCase();
if (!PERIOD_MAP_KEYS.includes(p)) {
throw new Error(`Unknown period "${p}". Valid: ${PERIOD_MAP_KEYS.join(', ')}`);
}
return p;
} Type guard
function isValidPeriod(p) {
return typeof p === 'string' && ['day', 'week', 'month'].includes(p.toLowerCase());
} Try / catch
try {
return await kline({ symbol, period: validatePeriod(userPeriod) });
} catch (err) {
if (err.code === 'INVALID_ARGUMENT' && err.message.startsWith('Unknown period')) {
console.warn(`${err.message} — falling back to 'day'`);
return kline({ symbol, period: 'day' });
}
throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- INVALID_ARGUMENT
- Unknown privacy "${privacy}". Valid: ${PRIVACY.join(', ')}
- --after must be a seq number or messageId UUID (got "${after
- --before must be a seq number (got "${before}")
- INVALID_ARGUMENT
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/180d6bb85a3f9abd.
Report an issue: GitHub.