n8n-io/n8n · error
Unsupported format for "${attachment.fileName}" (${attachmen
Error message
Unsupported format for "${attachment.fileName}" (${attachment.mimeType}). Supported: csv, tsv, json What it means
Thrown by parseStructuredFile when detectFormat returns a falsy value or returns a format that is not a legacy tabular format (csv/tsv/json) — see isLegacyTabularFormat at structured-file-parser.ts:66. parseStructuredFile only handles csv, tsv, and json; xlsx/html/pdf/docx/markdown/text each have dedicated extractors and must not be routed here.
Source
Thrown at packages/@n8n/instance-ai/src/parsers/structured-file-parser.ts:386
attachmentIndex: number,
input: ParseFileInput,
): ParseFileOutput {
// Decode base64
let decoded: Buffer;
try {
decoded = Buffer.from(attachment.data, 'base64');
} catch {
throw new Error('Failed to decode base64 attachment data');
}
if (decoded.length > MAX_DECODED_SIZE_BYTES) {
throw new Error(formatSizeLimitMessage(decoded.length));
}
const content = decoded.toString('utf-8');
const format = detectFormat(attachment.fileName, attachment.mimeType, input.format);
if (!format || !isLegacyTabularFormat(format)) {
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})`);View on GitHub (pinned to 5ac6606e81)
Solutions
- Route xlsx to extractXlsxAsRows and html/pdf/docx to their dedicated parsers instead of parseStructuredFile.
- Set a correct mimeType on AttachmentInfo (e.g. text/csv, application/json).
- Rename the file to a recognized extension (.csv/.tsv/.json) so detectFormat can infer it.
- Pass input.format explicitly as 'csv' | 'tsv' | 'json' when the filename is ambiguous.
Example fix
// before: parseStructuredFile({ fileName: 'data.xlsx', mimeType: 'application/vnd...sheet', data }, 0, { format: 'xlsx' })
// after: await extractXlsxAsRows({ fileName: 'data.xlsx', mimeType: 'application/vnd...sheet', data }, 0, input) Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = new Set(['csv','tsv','json']);
function routeAttachment(mimeType: string, fileName: string) {
const ext = fileName.split('.').pop()?.toLowerCase();
if (mimeType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || ext === 'xlsx') return 'xlsx';
// ... text-like formats
const fmt = SUPPORTED.has(ext ?? '') ? ext : undefined;
if (!fmt) throw new Error(`Route to parseStructuredFile only for csv/tsv/json; got ${mimeType}/${fileName}`);
return fmt;
} Type guard
function isLegacyTabularFormat(f: unknown): f is 'csv' | 'tsv' | 'json' {
return f === 'csv' || f === 'tsv' || f === 'json';
} Try / catch
try { return parseStructuredFile(attachment, idx, input); }
catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported format for')) {
// dispatch to the format-specific extractor (xlsx/html/pdf/docx) instead
}
throw e;
} Prevention
- Route by mimeType to the correct extractor before calling parseStructuredFile.
- Set explicit input.format when the filename is ambiguous.
- Keep MIME_TO_FORMAT and isLegacyTabularFormat in sync when adding formats.
When it happens
Trigger: Calling parseStructuredFile with a format hint of 'xlsx', 'html', 'pdf', 'docx', 'text', or 'markdown'; or attaching a file whose name has no recognized extension and whose mimeType is not in MIME_TO_FORMAT. Also when input.format is set to an unsupported value explicitly.
Common situations: A caller routes an .xlsx through parseStructuredFile instead of extractXlsxAsRows; a fileName like 'data.dat' with an arbitrary mimeType; a format string typo; a new format added to SupportedFormat but not to isLegacyTabularFormat.
Related errors
- Nested ${Array.isArray(value) ? 'array' : 'object'} found at
- Unsupported attachment type: ${summary}
- xlsx "${attachment.fileName}" has no sheets.
- xlsx "${attachment.fileName}" sheet "${firstSheetName}" is e
- Cannot decrease maxIterations when resuming a run. Expected
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/38b6f0858507542f.
Report an issue: GitHub.