payloadcms/payload · error · APIError
Invalid upload instructions request
Error message
Invalid upload instructions request
What it means
The endpoint runs `isUploadInstructionsRequest`, a runtime type guard that verifies the parsed JSON has the exact shape Payload needs: `collectionSlug: string`, `filename: string`, `filesize: number` that is a **safe integer ≥ 0**, `mimeType: string`, and (if present) `docPrefix: string`. Any deviation throws HTTP 400. Notably `filesize` must be a non-negative safe integer — a float, negative, or value beyond `Number.MAX_SAFE_INTEGER` fails.
Source
Thrown at packages/payload/src/uploads/endpoints/uploadInstructions.ts:97
if (!collectionPermissions?.create && !collectionPermissions?.update) {
throw new Forbidden(req.t)
}
}
return uploadInstructions
? uploadInstructions.generate({ ...upload, overrideAccess, req })
: generateStagedUploadInstructions({ ...upload, req })
}
export const uploadInstructionsEndpoint: Endpoint = {
handler: async (req) => {
if (!req.json) {
throw new APIError('Content-Type expected to be application/json', 400)
}
const upload: unknown = await req.json()
if (!isUploadInstructionsRequest(upload)) {
throw new APIError('Invalid upload instructions request', 400)
}
return Response.json(await getUploadInstructions({ ...upload, req }))
},
method: 'post',
path: '/upload-instructions',
}
/**
* Stores or removes temporary files when no adapter-specific upload instructions are available.
* PUT keeps the file until it is used in a document request.
* DELETE removes a file the client no longer needs.
*/
export const stagedUploadEndpoints: Endpoint[] = [
{
handler: uploadStagedFile,
method: 'put',
path: '/upload-instructions/:uploadId',View on GitHub (pinned to 00c58b35c0)
Solutions
- Validate the payload against `UploadInstructionsRequest` (collectionSlug/filename/mimeType strings, filesize a non-negative safe integer) before sending.
- Coerce `filesize` to `Math.max(0, Math.trunc(Number(filesize)))` and guard `Number.isSafeInteger`.
- Sync client types with the server's `UploadInstructionsRequest` interface from `payload`.
- Ensure the body is a flat object, not nested under a wrapper key.
Example fix
// before
fetch(`${url}/api/upload-instructions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
collection: 'media', // wrong key (should be collectionSlug)
filename: 'a.png',
filesize: '2048', // string, not number
mimeType: 'image/png',
}),
})
// after
const payload = {
collectionSlug: 'media',
filename: 'a.png',
filesize: 2048, // number, safe integer >= 0
mimeType: 'image/png',
}
fetch(`${url}/api/upload-instructions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
}) Defensive patterns
Strategy: type-guard
Validate before calling
function isUploadInstructionsRequest(u: unknown): u is UploadInstructionsRequest {
if (!u || typeof u !== 'object') return false
const o = u as Record<string, unknown>
return (
typeof o.collectionSlug === 'string' &&
typeof o.filename === 'string' &&
typeof o.mimeType === 'string' &&
typeof o.filesize === 'number' &&
Number.isSafeInteger(o.filesize) &&
o.filesize >= 0 &&
(o.docPrefix === undefined || typeof o.docPrefix === 'string')
)
}
const body = { collectionSlug: 'media', filename, filesize: Math.trunc(file.size), mimeType }
if (!isUploadInstructionsRequest(body)) {
throw new Error('Invalid upload-instructions payload')
} Type guard
const isUploadInstructionsRequest = (u: unknown): u is UploadInstructionsRequest => !!u && typeof u === 'object' && typeof (u as any).collectionSlug === 'string' && typeof (u as any).filename === 'string' && typeof (u as any).mimeType === 'string' && typeof (u as any).filesize === 'number' && Number.isSafeInteger((u as any).filesize) && (u as any).filesize >= 0
Try / catch
try {
if (!isUploadInstructionsRequest(payload)) throw new Error('bad shape')
await fetch(`${url}/api/upload-instructions`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) })
} catch (err) {
if (/invalid upload instructions request/i.test(String(err))) {
// fix field types and retry
}
} Prevention
- Share the `UploadInstructionsRequest` type from `payload` with the client.
- Coerce `filesize` to a non-negative safe integer before sending.
- Reject bodies where optional `docPrefix` is a non-string.
When it happens
Trigger: `POST /api/upload-instructions` whose JSON body is missing a required field, has a wrong-typed field (e.g. `filesize: "12345"` as a string), contains a negative or fractional `filesize`, or `docPrefix` is a non-string type. Also thrown if the body parses to a non-object or null.
Common situations: Client sends `filesize` as a string from a form field. `docPrefix` is accidentally an object. A field is omitted because the client schema is out of sync with the server version. The body is `null` or an array. `filesize` is `NaN` from a failed `parseInt`.
Related errors
- Invalid upload reference.
- Content-Type expected to be application/json
- Invalid file url
- storage contains an invalid entry: expected an object with a
- Field ${field.label} has reserved name '${fieldName}'.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/b8061217bb232c55.
Report an issue: GitHub.