n8n-io/n8n · error
Too many columns: ${rawHeaders.length} (max ${MAX_COLUMNS})
Error message
Too many columns: ${rawHeaders.length} (max ${MAX_COLUMNS}) What it means
Thrown on the JSON branch of parseStructuredFile (structured-file-parser.ts:403-404) when the number of unique keys across all objects in the JSON array exceeds MAX_COLUMNS (50). Headers are deduplicated via a Set that preserves first-appearance order, so the count is of distinct keys, not total fields.
Source
Thrown at packages/@n8n/instance-ai/src/parsers/structured-file-parser.ts:404
throw new Error(
`Unsupported format for "${attachment.fileName}" (${attachment.mimeType}). Supported: csv, tsv, json`,
);
}
const hasHeader = input.hasHeader ?? true;
const startRow = input.startRow ?? 0;
const maxRows = Math.min(input.maxRows ?? DEFAULT_MAX_ROWS, MAX_ROWS_PER_CALL);
const warnings: string[] = [];
let columns: ColumnMeta[];
let paginatedRows: Array<Record<string, CellValue>>;
let totalRows: number;
if (format === 'json') {
const { rawHeaders, allRows } = parseJson(content);
if (rawHeaders.length > MAX_COLUMNS) {
throw new Error(`Too many columns: ${rawHeaders.length} (max ${MAX_COLUMNS})`);
}
const normalizedNames = normalizeColumnNames(rawHeaders);
totalRows = allRows.length;
const sliced = allRows.slice(startRow, startRow + maxRows);
// Build columns with type inference from sliced sample
columns = rawHeaders.map((raw, i) => ({
originalName: raw,
name: normalizedNames[i],
inferredType: inferColumnType(
sliced.map((row) => {
const val = row[raw];
return val === undefined ? null : (val as CellValue);
}),
),
index: i,
}));View on GitHub (pinned to 5ac6606e81)
Solutions
- Project the JSON to only the columns the task needs before attaching.
- Split heterogeneous record types into separate attachments.
- Drop sparse/optional fields that inflate the distinct-key count.
- If the data is legitimately wide, summarize or sample it rather than passing it raw.
Example fix
// before: attach JSON with 73 distinct keys // after: attach JSON projected to the 12 relevant keys
Defensive patterns
Strategy: validation
Validate before calling
import { MAX_COLUMNS } from './structured-file-parser';
const keys = new Set<string>();
for (const item of parsed) for (const k of Object.keys(item)) keys.add(k);
if (keys.size > MAX_COLUMNS) throw new Error(`Too many columns: ${keys.size}`); Type guard
function isWithinColumnLimit(parsed: unknown[], limit = MAX_COLUMNS): boolean {
const keys = new Set<string>();
for (const item of parsed as Record<string, unknown>[]) for (const k of Object.keys(item)) keys.add(k);
return keys.size <= limit;
} Try / catch
try { return parseStructuredFile(attachment, idx, input); }
catch (e) {
if (e instanceof Error && e.message.startsWith('Too many columns')) {
// project to fewer keys and retry
}
throw e;
} Prevention
- Project JSON to only needed keys before attaching.
- Split heterogeneous record types into separate attachments.
- Measure distinct-key count before upload.
When it happens
Trigger: A JSON array attachment whose union of keys across all objects is > 50. Each new key seen adds to the count even if most rows leave it null.
Common situations: Wide REST responses; column-sparse JSON where different objects carry different optional fields; an export with many metadata columns; unions of heterogeneous record types concatenated into one array.
Related errors
- Dangerous key "${dangerousKey}" found in JSON data
- Nested ${Array.isArray(value) ? 'array' : 'object'} found at
- Attachment exceeds maximum size of 10.0 MB (got ${formatMB(a
- Attachment exceeds maximum size of 10.0 MB (got ${formatMB(a
- Failed to parse judge response as JSON: ${jsonStr.slice(0, 1
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/ced8fbfb2de990cd.
Report an issue: GitHub.