Budibase/budibase · error · HTTPError
file is required
Error message
file is required
What it means
Thrown by uploadAgentFile when the multipart request contains no file under any of the accepted field names ('file', 'knowledgeBaseFile', 'upload'). The controller normalizes ctx.request.files and, finding nothing, rejects with HTTP 400 because knowledge ingestion requires an actual uploaded file.
Source
Thrown at packages/server/src/api/controllers/ai/files.ts:190
ctx.status = 200
}
export async function uploadAgentFile(
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)View on GitHub (pinned to a81a902e9a)
Solutions
- Attach the file as multipart/form-data under the field name 'file' (or 'knowledgeBaseFile'/'upload').
- Verify the request Content-Type is multipart/form-data and the form has enctype='multipart/form-data'.
- Confirm the server's multipart body-parsing middleware is configured so ctx.request.files is populated.
- Check that no reverse proxy (e.g. nginx client_max_body_size) is dropping the file part.
Example fix
// before
await fetch(`/api/ai/agents/${agentId}/operations/${opId}/files`, { method: "POST", body: JSON.stringify({ data }) })
// after
const form = new FormData()
form.append("file", new Blob([buffer]), "doc.pdf")
await fetch(`/api/ai/agents/${agentId}/operations/${opId}/files`, { method: "POST", body: form }) Defensive patterns
Strategy: validation
Validate before calling
function hasUpload(files) {
return Boolean(files && (files.file || files.knowledgeBaseFile || files.upload))
}
if (!hasUpload(ctx.request.files)) throw new Error("file is required") Type guard
function isUploadedFile(f) {
return Boolean(f && typeof f === "object" && typeof (f.filepath ?? f.path) === "string")
} Try / catch
try {
const res = await api.uploadAgentFile(agentId, operationId, form)
} catch (err) {
if (err.status === 400 && err.message === "file is required") {
// prompt user to attach a file
} else throw err
} Prevention
- Always send multipart/form-data with the file under the 'file' field.
- Set enctype='multipart/form-data' on HTML forms.
- Verify middleware populates ctx.request.files before handlers run.
- Add a client-side check that a file is selected before submitting.
When it happens
Trigger: POSTing to the agent file upload endpoint without multipart/form-data; attaching the file under a field name other than file/knowledgeBaseFile/upload; sending a JSON body instead of multipart; body-parser middleware not enabled so ctx.request.files is undefined.
Common situations: Hand-rolled curl or fetch calls using the wrong form field name; Postman/Swagger requests left on raw JSON body type; frontend form missing enctype='multipart/form-data'; a proxy stripping the file part.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
- Invalid ${queryName} query
- Invalid environment query
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/bda6dbf951bc983e.
Report an issue: GitHub.