Budibase/budibase · error · HTTPError
Invalid upload payload
Error message
Invalid upload payload
What it means
Thrown when a file entry exists in ctx.request.files but the normalized upload object exposes neither filepath nor path, so the controller cannot locate the temp file on disk. Indicates a malformed or non-standard upload payload shape rather than a missing file.
Source
Thrown at packages/server/src/api/controllers/ai/files.ts:194
ctx: UserCtx<
void,
AgentFileUploadResponse,
{ agentId: string; operationId: string }
>
) {
const { agentId, operationId } = ctx.params
const upload = normalizeUpload(
ctx.request.files?.file ||
ctx.request.files?.knowledgeBaseFile ||
ctx.request.files?.upload
)
if (!upload) {
throw new HTTPError("file is required", 400)
}
const filePath = upload.filepath || upload.path
if (!filePath) {
throw new HTTPError("Invalid upload payload", 400)
}
const filename = upload.originalFilename || upload.name || "agent-document"
const mimetype = upload.mimetype || upload.type
const fileSize =
typeof upload.size === "number"
? upload.size
: Number(upload.size) || undefined
if (!isKnowledgeFileSupported({ filename, mimetype })) {
await unlinkSafe(filePath)
throw new HTTPError("Unsupported file type for knowledge ingestion", 400)
}
const buffer = await readFile(filePath)
try {
const updated = await sdk.ai.rag.uploadFileForOperation(
agentId,View on GitHub (pinned to a81a902e9a)
Solutions
- Use the standard multipart parser configuration so uploads expose filepath (tmp-file storage, e.g. formidable defaults).
- Inspect the parsed upload object shape and confirm it has filepath or path before the handler runs.
- Check middleware ordering so multipart parsing executes before the route handler.
- Send a genuine file part (not a text field) named file/knowledgeBaseFile/upload.
Example fix
// before
app.use(koaBody({ multipart: true }))
// after
app.use(koaBody({ multipart: true, formidable: { uploadDir: os.tmpdir(), keepExtensions: true } })) Defensive patterns
Strategy: type-guard
Validate before calling
const upload = files?.file || files?.knowledgeBaseFile || files?.upload
const filePath = upload?.filepath || upload?.path
if (!filePath) throw new Error("Invalid upload payload") Type guard
function hasReadablePath(u) {
return Boolean(u && typeof u === "object" && (typeof u.filepath === "string" || typeof u.path === "string"))
} Try / catch
try {
await uploadAgentFile(ctx)
} catch (err) {
if (err.message === "Invalid upload payload") {
// inspect parser config / upload object shape
} else throw err
} Prevention
- Keep the standard multipart parser with tmp-file storage so uploads expose filepath.
- Do not insert custom middleware that reshapes ctx.request.files.
- Log the parsed upload object once when upgrading parsing libraries.
- Send real file parts, not coerced text fields.
When it happens
Trigger: The multipart parser produced an upload object lacking both filepath and path (e.g. a memoryStorage parser returning a Buffer without a path); custom middleware reshaping ctx.request.files; a client sending form values coerced into 'file' fields instead of real file parts.
Common situations: Switching koa-body/busboy options (multipart, memoryStorage) without accounting for the different upload shape; custom normalization middleware dropping fields; using a non-standard parsing library that stores content under different keys.
Related errors
- file is required
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
- Invalid ${queryName} query
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/67098ed634448f29.
Report an issue: GitHub.