Budibase/budibase · error · HTTPError
A custom REST template named "${name.trim()}" already exists
Error message
A custom REST template named "${name.trim()}" already exists What it means
A 409 HTTPError thrown when a template with the same kebab-cased name already exists, detected by scanning the workspace's existing templates via fetch(). This is the name-uniqueness check performed before generating the new template id.
Source
Thrown at packages/server/src/sdk/workspace/restTemplates.ts:102
const createWithoutLock = async ({
name,
description,
data,
fileExtension,
operationsCount,
}: CreateCustomRestTemplateParams): Promise<RestTemplate> => {
const db = context.getWorkspaceDB()
const normalizedName = kebabCase(name)
if (!normalizedName) {
throw new HTTPError("Template name must contain letters or numbers", 400)
}
const existingTemplate = (await fetch()).find(
template => kebabCase(template.name) === normalizedName
)
if (existingTemplate) {
throw new HTTPError(
`A custom REST template named "${name.trim()}" already exists`,
409
)
}
const restTemplateId = dbCore.generateRestTemplateID()
const existing = await db.tryGet<CustomRestTemplateDocument>(restTemplateId)
if (existing) {
throw new HTTPError(
`A custom REST template named "${name.trim()}" already exists`,
409
)
}
const folder = getObjectStoreFolder(restTemplateId)
const objectStoreKey = `${folder}/openapi.${fileExtension}`
const document: CustomRestTemplateDocument = {
_id: restTemplateId,View on GitHub (pinned to a81a902e9a)
Solutions
- Check the returned 409 and surface 'name already in use' to the user, prompting for a new name
- Pre-check with fetch() (list templates) and compare kebabCase(name) before creating
- Append a distinguishing suffix (version, timestamp) to guarantee uniqueness
- Deduplicate concurrent submissions by disabling the create action once in flight
Example fix
// before
await restTemplates.create({ name: "My API" }) // 409 if "my-api" exists
// after
const exists = (await restTemplates.fetch()).some(t => kebabCase(t.name) === "my-api")
if (!exists) await restTemplates.create({ name: "My API" }) Defensive patterns
Strategy: validation
Validate before calling
const taken = (await restTemplates.fetch()).some(t => kebabCase(t.name) === kebabCase(name))
if (taken) throw new Error(`A template named "${name}" already exists`) Type guard
null
Try / catch
try {
await restTemplates.create({ name })
} catch (e) {
if (e?.status === 409) {
// prompt the user for a different name
return
}
throw e
} Prevention
- Compare names after kebabCase since 'My API' and 'my-api' collide
- Disable the create button while a request is in flight to prevent double submits
- Auto-suffix duplicate names in batch/automation workflows
- Keep the template list fresh so pre-checks see recent creations
When it happens
Trigger: Calling create with a name whose kebabCase form equals an existing template's kebabCased name — including names differing only in case, spacing, or separators ("My Template" vs "my-template"), or the exact same create call submitted twice.
Common situations: User clicks 'Create' twice quickly; duplicating a template in the UI without renaming; two workspace admins creating identically named templates concurrently; kebab-case collisions like "REST v2" and "rest-v2".
Related errors
- Email already in use: '${email}'
- Email already in use: '${email}'
- Group name "${name}" is unavailable
- Custom REST template cannot be deleted while it is in use
- Agent with name '${name}' already exists.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/75ec665c8a06214d.
Report an issue: GitHub.