Budibase/budibase · error · HTTPError

Invalid custom REST template ID

Error message

Invalid custom REST template ID

What it means

This 400 HTTPError is thrown by the REST template update controller when the restTemplateId URL parameter fails the isCustomRestTemplateId check from shared-core. Custom template IDs have a reserved format; arbitrary or system template IDs are rejected before any body validation occurs.

Source

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

        fileExtension,
        operationsCount: info.endpoints.length,
      }),
    }
  } finally {
    await unlink(uploadDetails.filepath).catch(() => {})
  }
}

export const update = async (
  ctx: UserCtx<
    UploadCustomRestTemplateRequest,
    UpdateCustomRestTemplateResponse,
    { restTemplateId: string }
  >
) => {
  const { restTemplateId } = ctx.params
  if (!isCustomRestTemplateId(restTemplateId)) {
    throw new HTTPError("Invalid custom REST template ID", 400)
  }

  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)
  }

  ctx.body = {
    template: await sdk.restTemplates.update({
      restTemplateId,
      name,
      description,
    }),
  }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Fetch the template list first and use a restTemplateId returned by the fetch endpoint
  2. Verify the ID matches the custom template ID format (isCustomRestTemplateId) before calling
  3. Retry with the ID of an actual custom-uploaded template

Example fix

// before
PUT /api/restTemplates/builtin_petstore  // not a custom ID
// after
const templates = await fetch("/api/restTemplates").then(r => r.json())
const id = templates.find(t => t.custom).id
await fetch(`/api/restTemplates/${id}`, { method: "PUT", ... })
Defensive patterns

Strategy: validation

Validate before calling

import { isCustomRestTemplateId } from "@budibase/shared-core"
if (!isCustomRestTemplateId(id)) {
  throw new Error("Refusing to update: not a custom REST template ID")
}

Type guard

import { isCustomRestTemplateId } from "@budibase/shared-core"
// use directly as the type guard before calling the API

Try / catch

try {
  await updateTemplate(id, body)
} catch (e) {
  if (e?.status === 400 && /Invalid custom REST template ID/.test(e?.message)) {
    // refresh template list and pick a valid custom ID
  } else throw e
}

Prevention

When it happens

Trigger: PUT/PATCH to the update endpoint with a malformed ID, an ID belonging to a built-in (non-custom) template, or a truncated/random ID in the URL path.

Common situations: Hardcoded IDs copied from docs or other environments; calling update on a built-in template ID; stale IDs cached from a previous workspace.

Related errors


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