nanocoai/nanoclaw · error · Error
${flag} must be valid JSON
Error message
${flag} must be valid JSON What it means
A flag declared with `type: 'json'` must parse as JSON when passed as a string. JSON.parse threw, and the error is re-thrown with the parse failure as `cause` so the exact syntax problem is preserved.
Source
Thrown at src/cli/crud.ts:439
switch (def.type) {
case 'number': {
const n = Number(v);
if (Number.isNaN(n)) throw new Error(`${flag} must be a number, got "${v}"`);
out[def.name] = n;
break;
}
case 'boolean': {
if (v === true || v === 'true' || v === '1') out[def.name] = true;
else if (v === false || v === 'false' || v === '0') out[def.name] = false;
else throw new Error(`${flag} must be true or false, got "${v}"`);
break;
}
case 'json': {
if (typeof v === 'string') {
try {
out[def.name] = JSON.parse(v);
} catch (err) {
throw new Error(`${flag} must be valid JSON`, { cause: err });
}
}
break;
}
case 'string':
out[def.name] = String(v);
break;
}
if (def.enum && !def.enum.includes(String(out[def.name]))) {
throw new Error(`${flag} must be one of: ${def.enum.join(', ')}`);
}
}
return out;
}
// ---------------------------------------------------------------------------
// registerResource
// ---------------------------------------------------------------------------View on GitHub (pinned to 294ef2aee8)
Solutions
- Wrap the JSON in single quotes so the shell passes it verbatim: `--payload '{"key": 1}'`
- Validate the payload with `echo '<json>' | jq .` before running the command
- Use the `--flag=value` form to avoid tokenization issues
- Inspect `error.cause` for the precise JSON.parse position
Example fix
# before
ncl groups config update --id g1 --mounts {/data:/data}
# Error: --mounts must be valid JSON
# after
ncl groups config update --id g1 --mounts '{"/data":"/data"}' Defensive patterns
Strategy: validation
Validate before calling
if (typeof v === 'string') { try { JSON.parse(v); } catch { throw new Error('payload is not valid JSON — check quoting'); } } Type guard
function isValidJsonString(v: string): boolean {
try { JSON.parse(v); return true; } catch { return false; }
} Try / catch
catch (e) { if (e instanceof Error && /must be valid JSON/.test(e.message)) { /* inspect e.cause for parse position, fix quoting */ } else throw e; } Prevention
- Wrap JSON payloads in single quotes at the shell
- Pipe through `jq .` as a pre-flight check
- Use --flag='...' syntax to avoid word splitting
When it happens
Trigger: Passing unquoted or shell-mangled JSON (`--config {a:1}` — unquoted keys are invalid JSON); single-quote wrapping stripped by the shell leaving bare braces that trigger globbing or splitting; trailing commas; passing a filename instead of file contents; passing YAML instead of JSON.
Common situations: Shell quoting mistakes with nested quotes (`--payload "{\"k\":1}"` done wrong); agents emitting pretty-printed multi-line JSON the shell splits on spaces; forgetting that JSON requires double-quoted strings.
Related errors
- unknown flag --${key.replace(/_/g, '-')}
- ${flag} is required
- ${flag} requires a value
- ${flag} must be a number, got "${v}"
- ${flag} must be true or false, got "${v}"
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/341abb505e3da984.
Report an issue: GitHub.