Budibase/budibase · error · HTTPError
Agent with name '${name}' already exists.
Error message
Agent with name '${name}' already exists. What it means
guardName enforces unique agent names within a workspace. It compares normalizeForComparison(name) of the incoming name against all existing agents and, if another agent (different _id) matches case/whitespace-insensitively, throws a 400 HTTPError with this message naming the conflicting name.
Source
Thrown at packages/server/src/sdk/workspace/ai/agents/crud.ts:113
.map(row => row.doc)
.filter((doc): doc is DeprecatedAgent => !!doc)
}
const guardName = async (name: string, id?: string) => {
if (!name.trim()) {
throw new HTTPError(NAME_REQUIRED_ERROR, 400)
}
const agents = await fetchRaw()
const normalizedName = helpers.normalizeForComparison(name)
const duplicate = agents.find(
agent =>
helpers.normalizeForComparison(agent.name) === normalizedName &&
agent._id !== id
)
if (duplicate) {
throw new HTTPError(`Agent with name '${name}' already exists.`, 400)
}
}
const encodeSecret = (value?: string): string | undefined => {
if (!value || value.startsWith(SECRET_ENCODING_PREFIX)) {
return value
}
return `${SECRET_ENCODING_PREFIX}${encryption.encrypt(value)}`
}
const decodeSecret = (value?: string): string | undefined => {
if (!value || !value.startsWith(SECRET_ENCODING_PREFIX)) {
return value
}
return encryption.decrypt(value.slice(SECRET_ENCODING_PREFIX.length))
}
const encodeSlackIntegrationSecrets = (View on GitHub (pinned to a81a902e9a)
Solutions
- Pick a unique name — check the existing agents list and adjust
- For renames that only change casing/spacing of the agent's own name, this is allowed (its own _id is excluded from the duplicate check); verify you are not accidentally targeting another agent's _id
- Pre-check uniqueness client-side using normalizeForComparison-equivalent logic before submitting
- Catch the 400 HTTPError and show the server message ('Agent with name ... already exists') in the UI
Example fix
// before
await sdk.ai.agents.create({ name: "Support Agent" }) // may 400
// after
const existing = await sdk.ai.agents.fetch()
if (existing.some(a => a.name.trim().toLowerCase() === "support agent")) {
name = "Support Agent 2"
}
await sdk.ai.agents.create({ name }) Defensive patterns
Strategy: validation
Validate before calling
const agents = await sdk.ai.agents.fetch()
const normalized = name.trim().toLowerCase()
if (agents.some(a => a.name.trim().toLowerCase() === normalized && a._id !== id)) {
throw new Error(`Agent with name '${name}' already exists.`)
} Try / catch
try {
await sdk.ai.agents.update({ ...agent, name })
} catch (err) {
if (err instanceof HTTPError && err.status === 400 && /already exists/.test(err.message)) {
// prompt the user for a different name
} else { throw err }
} Prevention
- Pre-check name uniqueness (normalized) in the UI before submitting
- Remember matching is case/whitespace-insensitive
- Handle the 400 in form error state with the server message
When it happens
Trigger: Creating an agent whose name matches an existing one, or updating an agent to a name already used by a different agent (id !== existing _id). Matching is normalized, so "VPN Agent" collides with "vpn agent" or " VPN Agent ".
Common situations: Users renaming an agent to a name that already exists; duplicate imports/seed scripts creating the same agent twice; UI not pre-checking uniqueness; case-only renames where the user thinks they are renaming but the API treats it as a duplicate of another agent, or vice versa when renaming an agent to its own name is fine (same _id passes).
Related errors
- Agent name is required.
- agentId is required
- _id and _rev are required
- Operation with name '${operationName?.trim()}' already exist
- Invalid bookmark query
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/95f61e5a440f72eb.
Report an issue: GitHub.