jackwener/OpenCLI · error · ArgumentError
--expiration must use YYYY-MM-DD format
Error message
--expiration must use YYYY-MM-DD format
What it means
normalizeExpiration() accepts an optional --expiration value but enforces strict YYYY-MM-DD formatting when one is provided. Any string that does not match the /^\d{4}-\d{2}-\d{2}$/ pattern throws this ArgumentError. It is a format-only check; the calendar-validity check is a separate error.
Source
Thrown at clis/barchart/greeks.js:23
*/
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
const DEFAULT_LIMIT = 10;
const MIN_LIMIT = 1;
const MAX_LIMIT = 100;
function normalizeSymbol(value) {
const symbol = String(value ?? '').trim().toUpperCase();
if (!symbol) throw new ArgumentError('symbol is required');
return symbol;
}
function normalizeExpiration(value) {
const expiration = String(value ?? '').trim();
if (!expiration) return '';
if (!/^\d{4}-\d{2}-\d{2}$/.test(expiration)) {
throw new ArgumentError('--expiration must use YYYY-MM-DD format');
}
const parsed = new Date(`${expiration}T00:00:00Z`);
if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== expiration) {
throw new ArgumentError('--expiration must be a valid calendar date');
}
return expiration;
}
function parseLimit(value) {
if (value === undefined || value === null || value === '') return DEFAULT_LIMIT;
const limit = Number(value);
if (!Number.isInteger(limit) || limit < MIN_LIMIT || limit > MAX_LIMIT) {
throw new ArgumentError(`--limit must be an integer between ${MIN_LIMIT} and ${MAX_LIMIT}`);
}
return limit;
}
function unwrapBrowserResult(value) {View on GitHub (pinned to 49907e53dc)
Solutions
- Reformat the value to YYYY-MM-DD, e.g. --expiration 2025-12-20.
- In scripts, convert locale-formatted dates with a formatting step (e.g. date.toISOString().slice(0,10)) before passing them.
- Quote the argument in the shell so dashes/spaces are not mangled.
Example fix
// before --expiration 12/20/2025 // after --expiration 2025-12-20
Defensive patterns
Strategy: validation
Validate before calling
function toIsoDate(d) {
const date = d instanceof Date ? d : new Date(d);
if (Number.isNaN(date.getTime())) throw new Error(`Invalid date: ${d}`);
return date.toISOString().slice(0, 10); // always YYYY-MM-DD
}
// call: toIsoDate('12/20/2025') => '2025-12-20' Type guard
function isIsoDateString(v) {
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
} Try / catch
try {
await greeks({ symbol, expiration });
} catch (e) {
if (e.name === 'ArgumentError' && e.message.includes('YYYY-MM-DD')) {
console.error(`--expiration must be YYYY-MM-DD, got: ${expiration}`);
process.exitCode = 2;
return;
}
throw e;
} Prevention
- Normalize all dates to YYYY-MM-DD via toISOString().slice(0,10) before passing
- Never pass locale-formatted (MM/DD/YYYY) dates directly
- Quote date arguments in shell scripts
When it happens
Trigger: Passing --expiration values like 12/20/2025, 2025-12-20T00:00:00, 20251220, 25-12-20, or any other string not exactly four digits, dash, two digits, dash, two digits.
Common situations: Using US-style MM/DD/YYYY dates from spreadsheets; copy-pasting a full ISO timestamp including time; locale-formatted dates from scripts; passing an expiration with surrounding units or labels like '2025-12-20T'.
Related errors
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
- archive search query must not be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5fc01b5a49e7ba74.
Report an issue: GitHub.