n8n-io/n8n · error · NodeOperationError
${file.error?.message ?? 'Unknown error'}
Error message
${file.error?.message ?? 'Unknown error'} What it means
Streamed-upload counterpart of [848]. In transferFile, after uploadStream finishes and the code polls the File until ACTIVE/FAILED, a FAILED state throws file.error?.message ?? 'Unknown error' with description 'Error uploading file'. Same semantic as the buffer path but reached via the streaming transferFile helper.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vendors/GoogleGemini/helpers/utils.ts:242
if ('buffer' in fileData) {
return await uploadFile.call(this, fileData.buffer, fileData.mimeType);
}
const { stream, mimeType } = fileData;
const uploadResponse = (await uploadStream.call(this, stream, {
endpoint: '/upload/v1beta/files',
mimeType,
})) as { body: { file: File } };
let file = uploadResponse.body.file;
while (file.state !== 'ACTIVE' && file.state !== 'FAILED') {
await new Promise((resolve) => setTimeout(resolve, OPERATION_CHECK_INTERVAL));
file = (await apiRequest.call(this, 'GET', `/v1beta/${file.name}`)) as File;
}
if (file.state === 'FAILED') {
throw new NodeOperationError(this.getNode(), file.error?.message ?? 'Unknown error', {
description: 'Error uploading file',
});
}
return { fileUri: file.uri, mimeType: file.mimeType };
}
export async function createFileSearchStore(this: IExecuteFunctions, displayName: string) {
return (await apiRequest.call(this, 'POST', '/v1beta/fileSearchStores', {
body: { displayName },
})) as IDataObject;
}
export async function uploadToFileSearchStore(
this: IExecuteFunctions,
i: number,
fileSearchStoreName: string,
displayName: string,View on GitHub (pinned to 5ac6606e81)
Solutions
- Read file.error.message — it carries Google's reason for the FAILED state.
- Re-encode the source to a supported MIME; reduce size; retry on transient errors.
- If downloading from a URL, first fetch and validate the content-type matches a Gemini-supported type before transferFile.
Defensive patterns
Strategy: retry
Validate before calling
function isSupportedForUpload(contentType: string | undefined): boolean {
const SUPPORTED = ['application/pdf','image/png','image/jpeg','image/webp','audio/mpeg','audio/wav','video/mp4'];
return !!contentType && SUPPORTED.includes(contentType.split(';')[0]);
} Type guard
function isStreamableUploadFailure(file: { state: string; error?: { message: string } }): boolean {
return file.state === 'FAILED';
} Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
try { return await transferFile(i, url, mime); }
catch (e) {
if (attempt === 3 || /unsupported|too large/i.test(e.message)) throw e;
await new Promise(r => setTimeout(r, 1000 * attempt));
}
} Prevention
- When transferring from a URL, fetch and check the content-type before piping to Gemini.
- Keep source files within Gemini's documented size limits.
- Retry once on FAILED — it can be transient.
When it happens
Trigger: transferFile is used (URL or binary-as-stream source) and Google reports the uploaded file's state as FAILED — same causes as [848]: unsupported type, too large, safety rejection, or backend error.
Common situations: Downloading a remote file (HTTP Request → URL) and piping it straight to Gemini where the format is rejected; streaming a large media file that exceeds tier limits.
Related errors
- ${uploadResponse.file.error?.message ?? 'Unknown error'}
- Failed to get upload URL
- ${response.error.message}
- Binary property name or download URL is required
- ${operation.error.message ?? 'Unknown error'}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/19de70f2e4fc27e6.
Report an issue: GitHub.