jackwener/OpenCLI · error · ArgumentError
${label} must be one of: ${Object.keys(choices).join(', ')}
Error message
${label} must be one of: ${Object.keys(choices).join(', ')} What it means
normalizeChoice validates an option against a fixed set of allowed keys (used for eventType, ranking, map, version options). It throws when the stringified value is not one of the accepted choices, listing all valid keys in the message.
Source
Thrown at clis/hltv/utils.js:82
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) throw new ArgumentError(`${label} must be a positive integer`);
if (n > maxValue) throw new ArgumentError(`${label} must be <= ${maxValue}`);
return n;
}
export function normalizeOffset(value, defaultValue = 0) {
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n < 0) throw new ArgumentError('offset must be a non-negative integer');
if (n % 100 !== 0) throw new ArgumentError('offset must be a multiple of 100');
return n;
}
export function normalizeChoice(value, defaultValue, choices, label) {
const raw = String(value ?? defaultValue);
if (!Object.prototype.hasOwnProperty.call(choices, raw)) {
throw new ArgumentError(`${label} must be one of: ${Object.keys(choices).join(', ')}`);
}
return raw;
}
export function parseNumber(value) {
const raw = String(value ?? '').replace(/\s+/g, ' ').trim();
if (!raw || raw === '-' || raw.toLowerCase() === 'n/a') return null;
const match = raw.replace(/,/g, '').match(/-?\d+(?:\.\d+)?/);
if (!match) return null;
const n = Number(match[0]);
return Number.isFinite(n) ? n : null;
}
export function parseMoneyUsd(value) {
return parseNumber(String(value ?? '').replace(/\$/g, ''));
}
export function absolutizeUrl(value) {View on GitHub (pinned to 49907e53dc)
Solutions
- Use one of the exact keys printed in the error message
- Run the command with --help to see the accepted choices for that option
- Check the library's CHANGELOG in case the option key was renamed between versions
Example fix
// before hltv maps --map de_dust2 // after hltv maps --map dust2 # use a key from the allowed list
Defensive patterns
Strategy: validation
Validate before calling
const MAPS = ['mirage','inferno','nuke','overpass','vertigo','ancient','anubis','dust2','train'];
if (opts.map && !MAPS.includes(String(opts.map).toLowerCase())) throw new Error(`map must be one of: ${MAPS.join(', ')}`); Type guard
const isChoice = (v, choices) => Object.prototype.hasOwnProperty.call(choices, String(v));
Try / catch
try {
await hltv.stats({ map: opts.map });
} catch (e) {
if (e.name === 'ArgumentError' && e.message.startsWith('map must be one of')) {
console.error(e.message); // message lists valid keys
process.exitCode = 2;
} else throw e;
} Prevention
- Build CLI choice menus from the same key list the library exports
- Lowercase/trim user input before comparing to choices
- Pin the library version and re-check choices after upgrades
When it happens
Trigger: Passing an unknown value like --map cache or --event-type lan when the mapping only defines specific keys; typos or casing differences; renamed options after a library update.
Common situations: Old scripts using choice keys removed in a newer version; guessing slug-style names instead of the exact keys; copy-pasting values from HLTV's UI rather than this CLI's list.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- ${label} must be one of: ${choices.join(', ')}
- unsupported notification type: ${value}
- 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
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8d113985edb108e5.
Report an issue: GitHub.