koala73/worldmonitor · error · UsageError
--args must be valid JSON: ${err.message}
Error message
--args must be valid JSON: ${err.message} What it means
In the worldmonitor CLI, an explicit --args value is passed verbatim to JSON.parse by collectArgs. Anything JSON.parse rejects — unquoted keys, single-quoted strings, trailing commas, shell-mangled quotes — raises UsageError embedding the parser's message, and run() maps it to exit code 2.
Source
Thrown at cli/src/core.mjs:204
function trimTrailingSlash(url) {
return url.replace(/\/+$/, '');
}
function baseHeaders(apiKey) {
const headers = { 'user-agent': USER_AGENT };
if (apiKey) headers[API_KEY_HEADER] = apiKey;
return headers;
}
// Tool/query arguments: an explicit --args JSON object wins; otherwise the
// collected --key value params, with bare boolean flags kept as true.
function collectArgs(parsed) {
if (parsed.options.args !== undefined) {
try {
return JSON.parse(parsed.options.args);
} catch (err) {
throw new UsageError(`--args must be valid JSON: ${err.message}`);
}
}
const args = {};
for (const [k, v] of Object.entries(parsed.params)) args[k] = v === true ? true : String(v);
return args;
}
function mcpPlan(method, rpcParams, options, config, extra = {}) {
const mcpUrl = options.mcpUrl || config.mcpUrl || DEFAULT_MCP_URL;
const apiKey = options.apiKey || config.apiKey;
const rpc = { jsonrpc: '2.0', id: 1, method };
if (rpcParams !== undefined) rpc.params = rpcParams;
return {
kind: 'mcp',
url: mcpUrl,
method: 'POST',
headers: {
...baseHeaders(apiKey),View on GitHub (pinned to eeab0a219f)
Solutions
- Wrap the JSON in shell single quotes: --args '{"country_code":"IR"}'
- Or drop --args and use per-flag params: --country_code IR (bare boolean flags become true)
- Sanity-check the payload before invoking: echo '<your-json>' | jq .
- On Windows use escaped double quotes or a shell that supports single quotes
Example fix
# before
worldmonitor call get_country_risk --args "{country_code: 'IR',}" # UsageError: --args must be valid JSON
# after
worldmonitor call get_country_risk --args '{"country_code":"IR"}'
# or skip JSON entirely
worldmonitor call get_country_risk --country_code IR Defensive patterns
Strategy: validation
Validate before calling
// Validate --args before spawning the CLI
function parseCliArgs(json) {
try { return { ok: true, value: JSON.parse(json) }; }
catch (e) { return { ok: false, error: e.message }; }
}
const check = parseCliArgs(argsJson);
if (!check.ok) throw new Error(`--args is not valid JSON: ${check.error}`); Type guard
function isJsonObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Prevention
- Prefer per-flag params (--country_code IR) unless nested values are required
- Build --args programmatically (JSON.stringify) instead of string concatenation
- Pipe hand-written JSON through jq before using it in a command line
When it happens
Trigger: --args "{key:'val'}" (unquoted keys or single quotes); a trailing comma; double-quoted JSON whose inner quotes were stripped by the shell; flags accidentally concatenated into the --args value.
Common situations: Writing the JSON without single-quote shell wrapping so quotes and $ interpolate; converting from --key value syntax and leaving fragments behind; Windows cmd quoting rules; missing closing brace from manual editing.
Related errors
- `get` needs an API path, e.g. `worldmonitor get /api/health`
- `call` needs a tool name, e.g. `worldmonitor call get_countr
- `${command}` needs <${a.name}>. Usage: worldmonitor ${comman
- Unknown command: ${command || '(none)'}. Run `worldmonitor -
- get-china-decision-signals returned no canonical payload
AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21).
Data as JSON: /api/errors/576fd1a5157f69bc.
Report an issue: GitHub.