vercel/ai · error · InvalidArgumentError
Google batch input files must not exceed 2 GB.
Error message
Google batch input files must not exceed 2 GB.
What it means
Batch jobs upload requests as a single JSONL file to Google's Batch API, which caps input file size at 2 GB (googleBatchInputFileMaxBytes). experimental_doStartBatch checks the assembled Blob size before uploading and throws InvalidArgumentError if the file exceeds the limit, because Google would reject the upload anyway.
Source
Thrown at packages/google/src/google-batch.ts:266
if (fileParts == null) {
const { value } = await postJsonToApi({
url: createUrl,
headers,
body: inlineBatchBody,
failedResponseHandler: googleFailedResponseHandler,
successfulResponseHandler: createJsonResponseHandler(
googleBatchOperationSchema,
),
abortSignal: options.abortSignal,
fetch: this.batchConfig.fetch,
});
operation = value;
} else {
const inputFile = new Blob(fileParts, { type: 'application/jsonl' });
// Blob snapshots the strings, so release the potentially large input array.
fileParts.length = 0;
if (inputFile.size > googleBatchInputFileMaxBytes) {
throw new InvalidArgumentError({
argument: 'requests',
message: 'Google batch input files must not exceed 2 GB.',
});
}
const { value: uploadUrl } = await postJsonToApi({
url: `${this.getBaseOrigin()}/upload/v1beta/files`,
headers: combineHeaders(headers, {
'X-Goog-Upload-Protocol': 'resumable',
'X-Goog-Upload-Command': 'start',
'X-Goog-Upload-Header-Content-Length': String(inputFile.size),
'X-Goog-Upload-Header-Content-Type': 'application/jsonl',
}),
body: {
file: {
display_name: `${displayName}-input`,
},
},View on GitHub (pinned to 69428b1f8b)
Solutions
- Split the requests into multiple batches, each under 2 GB, and start several batch jobs.
- Remove or shrink inline data (use Cloud Storage URIs / file references instead of base64) to reduce JSONL size.
- Trim prompts or move large static content out of per-request payloads (e.g. into context caching where supported).
Example fix
// before
await model.experimental_doStartBatch({ requests: allRequests }); // > 2GB
// after
for (const chunk of chunks(allRequests, 10_000)) {
await model.experimental_doStartBatch({ requests: chunk });
} Defensive patterns
Strategy: validation
Validate before calling
const MAX_BYTES = 2 * 1024 ** 3;
function validateBatchSize(requests) {
const size = new Blob(requests.map(r => JSON.stringify(r) + '\n')).size;
if (size > MAX_BYTES) throw new Error(`Batch payload ${size} bytes exceeds 2 GB; split into multiple batches.`);
return size;
} Type guard
null
Try / catch
try {
await model.experimental_doStartBatch({ requests });
} catch (e) {
if (e?.name === 'AI_InvalidArgumentError' && /2 GB/.test(e.message ?? '')) {
// split requests into chunks and start multiple batch jobs
} else throw e;
} Prevention
- Estimate serialized JSONL size before starting a batch and chunk accordingly.
- Avoid inline base64 media in batch requests; use Cloud Storage URIs.
- Monitor batch payload growth in CI with a size assertion on fixtures.
When it happens
Trigger: Calling `model.experimental_doStartBatch({ requests })` (or the batch helper) with a request array whose serialized JSONL exceeds 2,147,483,648 bytes - typically very large prompts, inline file/image data, or simply too many requests.
Common situations: Batch-embedding large document corpora with inline attachments; long-running backfills of thousands of requests with big system prompts; accidentally embedding base64 media in batch requests.
Related errors
- targetLanguage is required for translation model '${this.mod
- The Gemini Live translation API only supports 16kHz 16-bit P
- maxEmbeddingsPerCall must be greater than 0
- maxInputBytesPerCall must be greater than 0
- No image generated.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/a55134dc9c94aec8.
Report an issue: GitHub.