nanocoai/nanoclaw · error · StdinJsonInputError
--stdin-json key "__proto__" is not allowed
Error message
--stdin-json key "__proto__" is not allowed
What it means
assertNoKeyConflicts rejects the key "__proto__" in --stdin-json input. Assigning it would set the merged args object's prototype instead of an own key, a prototype-pollution vector, so it is rejected outright.
Source
Thrown at src/cli/stdin-json.ts:112
* is stdin-vs-argv or two stdin keys.
*
* `__proto__` is rejected outright as a prototype-pollution guard: parsed
* args flow into downstream handlers that copy them by plain assignment.
*/
function assertNoKeyConflicts(
stdinArgs: Readonly<Record<string, unknown>>,
argvArgs: Readonly<Record<string, unknown>>,
): void {
const argvKeysByCanonical = new Map<string, string>();
for (const key of Object.keys(argvArgs)) {
const canonical = canonicalArgKey(key);
if (!argvKeysByCanonical.has(canonical)) argvKeysByCanonical.set(canonical, key);
}
const stdinKeysByCanonical = new Map<string, string>();
for (const key of Object.keys(stdinArgs)) {
if (key === '__proto__') {
throw new StdinJsonInputError('--stdin-json key "__proto__" is not allowed');
}
if (Object.prototype.hasOwnProperty.call(argvArgs, key)) {
throw new StdinJsonInputError(`--stdin-json key "${key}" is also supplied on argv`);
}
const canonical = canonicalArgKey(key);
const argvKey = argvKeysByCanonical.get(canonical);
if (argvKey !== undefined) {
throw new StdinJsonInputError(
`--stdin-json key "${key}" conflicts with argv key "${argvKey}" after CLI key normalization`,
);
}
const priorStdinKey = stdinKeysByCanonical.get(canonical);
if (priorStdinKey !== undefined) {
throw new StdinJsonInputError(
`--stdin-json keys "${priorStdinKey}" and "${key}" conflict after CLI key normalization`,View on GitHub (pinned to 294ef2aee8)
Solutions
- Remove the __proto__ key from the input
- Use only plain argument keys
Example fix
# before
echo '{"__proto__": {}, "name": "x"}' | ncl groups create --stdin-json
# after
echo '{"name": "x"}' | ncl groups create --stdin-json Defensive patterns
Strategy: validation
Validate before calling
if (Object.prototype.hasOwnProperty.call(args, '__proto__')) throw new Error('rejected');
// safer parse: JSON.parse yields own keys only Prevention
- Never accept untrusted JSON merged with Object.assign; use JSON.parse
When it happens
Trigger: Passing {"__proto__": {...}} in the stdin JSON — usually a test of the guard or a crafted payload.
Common situations: Security testing, or accidentally merging an object whose prototype was serialized.
Related errors
- --stdin-json input exceeds ${MAX_STDIN_JSON_BYTES} bytes
- --stdin-json input is empty
- --stdin-json input is not valid JSON
- --stdin-json input must be one JSON object
- --stdin-json key "${key}" is also supplied on argv
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/5c6d7cb714b9a1bb.
Report an issue: GitHub.