n8n-io/n8n · error

Dangerous key "${dangerousKey}" found in JSON data

Error message

Dangerous key "${dangerousKey}" found in JSON data

What it means

Thrown by parseJson() inside parseStructuredFile when a JSON array object contains a key named __proto__, constructor, or prototype (see the DANGEROUS_KEYS set at structured-file-parser.ts:49). The guard runs before keys are collected as column headers, so prototype-polluting payloads can never reach downstream row/column processing. It is a hard security refusal, not a recoverable shape problem.

Source

Thrown at packages/@n8n/instance-ai/src/parsers/structured-file-parser.ts:340

	}

	if (!Array.isArray(parsed)) {
		throw new Error('Expected a JSON array of objects, got a single value or object');
	}

	if (parsed.length === 0) {
		return { rawHeaders: [], allRows: [] };
	}

	// Collect all keys across all objects (preserving order of first appearance)
	const keySet = new Set<string>();
	for (const item of parsed) {
		if (typeof item !== 'object' || item === null || Array.isArray(item)) {
			throw new Error('JSON array items must be flat objects (not arrays, nulls, or primitives)');
		}
		const dangerousKey = hasDangerousKey(item as Record<string, unknown>);
		if (dangerousKey) {
			throw new Error(`Dangerous key "${dangerousKey}" found in JSON data`);
		}
		for (const key of Object.keys(item as Record<string, unknown>)) {
			keySet.add(key);
		}
	}

	const rawHeaders = [...keySet];

	// Validate all values are flat
	for (const item of parsed) {
		const obj = item as Record<string, unknown>;
		for (const [key, value] of Object.entries(obj)) {
			if (value !== null && typeof value === 'object') {
				throw new Error(
					`Nested ${Array.isArray(value) ? 'array' : 'object'} found at key "${key}". Only flat objects are supported.`,
				);
			}
		}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Inspect the JSON for the keys __proto__, constructor, or prototype and rename or strip them before parsing.
  2. If the source is xlsx, open the sheet and rename the offending column header.
  3. Pre-validate the parsed JSON with your own hasDangerousKey check (structured-file-parser.ts:261) to give a clearer upstream error.
  4. Reject the attachment at the MIME-validation layer if it cannot be trusted.

Example fix

// before: [{ "__proto__": { "admin": true }, "name": "x" }]
// after:  [{ "name": "x" }]
Defensive patterns

Strategy: validation

Validate before calling

const DANGEROUS = new Set(['__proto__','constructor','prototype']);
function hasDangerousKey(obj: Record<string, unknown>): string | undefined {
  for (const key of Object.keys(obj)) if (DANGEROUS.has(key)) return key;
  return undefined;
}
// run before parseStructuredFile:
const parsed = JSON.parse(content);
for (const item of parsed) {
  const bad = hasDangerousKey(item);
  if (bad) throw new Error(`Refusing to attach: dangerous key "${bad}"`);
}

Type guard

function isSafeFlatObject(v: unknown): v is Record<string, string | number | boolean | null> {
  if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;
  for (const key of Object.keys(v)) {
    if (DANGEROUS.has(key)) return false;
    const val = (v as Record<string, unknown>)[key];
    if (val !== null && typeof val === 'object') return false;
  }
  return true;
}

Try / catch

try { return parseStructuredFile(attachment, idx, input); }
catch (e) {
  if (e instanceof Error && e.message.startsWith('Dangerous key')) {
    // surface a sanitize prompt to the caller / LLM
  }
  throw e;
}

Prevention

When it happens

Trigger: An attachment with mimeType application/json (or an .xlsx round-tripped through JSON at xlsx-parser.ts:56) whose decoded content is a JSON array containing an object like {"__proto__": {...}} or {"constructor": "x"}. The check fires for every item in the array during header collection.

Common situations: Data exported from a tool that serializes class metadata; a user sanitizing/renaming columns to JS reserved names; an LLM-generated eval-data payload that includes prototype chains; a malicious or fuzzed attachment probing for prototype-pollution sinks.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/800ab04c8c4fcd97. Report an issue: GitHub.