{"record":{"id":"22908b125c7ee295","repo":"n8n-io/n8n","slug":"attachment-exceeds-maximum-size-of-10-0-mb-got-22908b","errorCode":null,"errorMessage":"Attachment exceeds maximum size of 10.0 MB (got ${formatMB(actualBytes)})","messagePattern":"Attachment exceeds maximum size of 10\\.0 MB \\(got (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/src/parsers/xlsx-parser.ts","lineNumber":25,"sourceCode":"\ttype ParseFileInput,\n\ttype ParseFileOutput,\n} from './structured-file-parser';\n\n/**\n * Extracts the first sheet of an `.xlsx` workbook as tabular rows.\n *\n * Strategy: convert the sheet to CSV text via SheetJS, then route through the\n * existing `parseStructuredFile` so column normalization, type inference, and\n * truncation budgets stay in one place.\n */\nexport async function extractXlsxAsRows(\n\tattachment: AttachmentInfo,\n\tattachmentIndex: number,\n\tinput: ParseFileInput,\n): Promise<ParseFileOutput> {\n\tconst decoded = Buffer.from(attachment.data, 'base64');\n\tif (decoded.length > MAX_DECODED_SIZE_BYTES) {\n\t\tthrow new Error(formatSizeLimitMessage(decoded.length));\n\t}\n\tassertOoxmlWithinBounds(decoded, attachment.fileName);\n\n\tconst XLSX = await import('@e965/xlsx');\n\n\tlet workbook: ReturnType<typeof XLSX.read>;\n\ttry {\n\t\tworkbook = XLSX.read(decoded, { type: 'buffer' });\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : 'unknown error';\n\t\tthrow new Error(`Failed to parse xlsx \"${attachment.fileName}\": ${message}`);\n\t}\n\n\tconst firstSheetName = workbook.SheetNames[0];\n\tif (!firstSheetName) {\n\t\tthrow new Error(`xlsx \"${attachment.fileName}\" has no sheets.`);\n\t}\n","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/src/parsers/xlsx-parser.ts#L7-L43","documentation":"Thrown by extractXlsxAsRows (xlsx-parser.ts:24-25) when the decoded .xlsx byte length exceeds MAX_DECODED_SIZE_BYTES (10MB). This is the xlsx-specific twin of error 503; the decoded (not base64) size is measured before SheetJS ever opens the workbook. A subsequent assertOoxmlWithinBounds check guards uncompressed (decompression-bomb) size separately.","triggerScenarios":"An .xlsx attachment whose decoded bytes > 10MB. Because .xlsx is a ZIP, the base64 string can be considerably smaller than the decoded buffer.","commonSituations":"A workbook with embedded images, many sheets, or large cached formula values; a file that is mostly formatting overhead; user assumes the base64 length is the enforced limit.","solutions":["Strip embedded media, unused sheets, and styling from the workbook.","Keep only the sheet the task needs and save as a lean .xlsx.","Convert the relevant sheet to CSV and attach as text/csv if a spreadsheet is not required.","Sample/filter rows before exporting."],"exampleFix":"// before: attach a 13MB .xlsx with embedded charts\n// after:  export the target sheet as CSV (~1MB) and attach as text/csv","handlingStrategy":"validation","validationCode":"import { MAX_DECODED_SIZE_BYTES } from './structured-file-parser';\nconst decoded = Buffer.from(attachment.data, 'base64');\nif (decoded.length > MAX_DECODED_SIZE_BYTES) {\n  throw new Error(`xlsx too large after decode: ${decoded.length} bytes`);\n}","typeGuard":"function xlsxWithinDecodedLimit(base64: string, limit = MAX_DECODED_SIZE_BYTES): boolean {\n  return Buffer.byteLength(base64, 'base64') <= limit;\n}","tryCatchPattern":"try { return await extractXlsxAsRows(attachment, idx, input); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('Attachment exceeds')) {\n    // strip embedded media / unused sheets, re-save, retry\n  }\n  throw e;\n}","preventionTips":["Remove embedded images, charts, and unused sheets before exporting.","Convert to CSV when a spreadsheet is not strictly needed.","Measure decoded (not base64) size before attaching."],"tags":["size-limit","xlsx","attachment-parsing","limits"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}