{"record":{"id":"bda6dbf951bc983e","repo":"Budibase/budibase","slug":"file-is-required","errorCode":null,"errorMessage":"file is required","messagePattern":"file is required","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/files.ts","lineNumber":190,"sourceCode":"  ctx.status = 200\n}\n\nexport async function uploadAgentFile(\n  ctx: UserCtx<\n    void,\n    AgentFileUploadResponse,\n    { agentId: string; operationId: string }\n  >\n) {\n  const { agentId, operationId } = ctx.params\n  const upload = normalizeUpload(\n    ctx.request.files?.file ||\n      ctx.request.files?.knowledgeBaseFile ||\n      ctx.request.files?.upload\n  )\n\n  if (!upload) {\n    throw new HTTPError(\"file is required\", 400)\n  }\n  const filePath = upload.filepath || upload.path\n  if (!filePath) {\n    throw new HTTPError(\"Invalid upload payload\", 400)\n  }\n\n  const filename = upload.originalFilename || upload.name || \"agent-document\"\n  const mimetype = upload.mimetype || upload.type\n  const fileSize =\n    typeof upload.size === \"number\"\n      ? upload.size\n      : Number(upload.size) || undefined\n  if (!isKnowledgeFileSupported({ filename, mimetype })) {\n    await unlinkSafe(filePath)\n    throw new HTTPError(\"Unsupported file type for knowledge ingestion\", 400)\n  }\n\n  const buffer = await readFile(filePath)","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/files.ts#L172-L208","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait fetch(`/api/ai/agents/${agentId}/operations/${opId}/files`, { method: \"POST\", body: JSON.stringify({ data }) })\n// after\nconst form = new FormData()\nform.append(\"file\", new Blob([buffer]), \"doc.pdf\")\nawait fetch(`/api/ai/agents/${agentId}/operations/${opId}/files`, { method: \"POST\", body: form })","handlingStrategy":"validation","validationCode":"function hasUpload(files) {\n  return Boolean(files && (files.file || files.knowledgeBaseFile || files.upload))\n}\nif (!hasUpload(ctx.request.files)) throw new Error(\"file is required\")","typeGuard":"function isUploadedFile(f) {\n  return Boolean(f && typeof f === \"object\" && typeof (f.filepath ?? f.path) === \"string\")\n}","tryCatchPattern":"try {\n  const res = await api.uploadAgentFile(agentId, operationId, form)\n} catch (err) {\n  if (err.status === 400 && err.message === \"file is required\") {\n    // prompt user to attach a file\n  } else throw err\n}","preventionTips":["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."],"tags":["http-400","validation","file-upload","multipart"],"backgroundTag":"missing-required-parameter","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}