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

  1. Remove the __proto__ key from the input
  2. 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

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


AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28). Data as JSON: /api/errors/5c6d7cb714b9a1bb. Report an issue: GitHub.