Budibase/budibase · error · HTTPError

Invalid OpenAPI template upload

Error message

Invalid OpenAPI template upload

What it means

After file count validation, `upload` calls `getUploadDetails(file)` which derives upload metadata (path/name) from the uploaded file. If it returns falsy — e.g. the file object lacks the expected `name`/`originalFilename`/path properties or is otherwise malformed — the controller throws this 400 HTTPError. It usually indicates the file object doesn't look like a normal multipart upload.

Source

Thrown at packages/server/src/api/controllers/restTemplate.ts:65

  ctx: UserCtx<void, FetchCustomRestTemplatesResponse>
) => {
  ctx.body = await sdk.restTemplates.fetch()
}

export const upload = async (
  ctx: UserCtx<
    UploadCustomRestTemplateRequest,
    UploadCustomRestTemplateResponse
  >
) => {
  const file = ctx.request.files?.file
  if (!file || Array.isArray(file)) {
    throw new HTTPError("Exactly one OpenAPI template file is required", 400)
  }

  const uploadDetails = getUploadDetails(file)
  if (!uploadDetails) {
    throw new HTTPError("Invalid OpenAPI template upload", 400)
  }

  try {
    const name = ctx.request.body.name
    const description = ctx.request.body.description
    if (typeof name !== "string" || !name.trim()) {
      throw new HTTPError("Template name is required", 400)
    }
    if (typeof description !== "string") {
      throw new HTTPError("Template description is required", 400)
    }

    const fileExtension = getFileExtension(uploadDetails.filename)
    const data = await readFile(uploadDetails.filepath, "utf8")
    let importer
    let info
    try {
      importer = await createImporter({ data })

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Send a proper multipart/form-data request including a filename (e.g. `curl -F file=@spec.yaml`)
  2. Verify the file object has standard fields (`originalFilename`/`name`, `filepath`) on the server
  3. Check that proxies/middleware aren't stripping multipart metadata
  4. Update tests to upload via multipart instead of raw buffers

Example fix

// before
await fetch(url, { method: "POST", body: fileBuffer }) // no multipart metadata
// after
const form = new FormData()
form.append("file", new Blob([fileBuffer]), "spec.yaml")
await fetch(url, { method: "POST", body: form })
Defensive patterns

Strategy: validation

Validate before calling

const f = formData.get("file")
if (!(f instanceof File) || !f.name || !f.name.trim()) {
  throw new Error("Uploaded file must include a filename")
}

Try / catch

try {
  await uploadRestTemplate(form)
} catch (e) {
  if (e.status === 400 && String(e.message).includes("Invalid OpenAPI template upload")) {
    // ensure the multipart part carries a filename and retry
  }
}

Prevention

When it happens

Trigger: Uploading with a client that omits the filename metadata (some HTTP libraries send a bare body), streaming endpoints that construct file objects without names, or middleware transformations that strip standard fields from the file object.

Common situations: Custom HTTP clients that send multipart without filename; proxies/gateways rewriting multipart parts and dropping metadata; tests posting raw buffers instead of proper multipart; unusual characters or empty filenames.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/2019a18eef43c56b. Report an issue: GitHub.