Dokploy/dokploy · warning · TRPCError
CONFLICT
CONFLICT
Error message
A tag with this name already exists in your organization
What it means
Thrown by tag.create when the underlying Postgres insert violates the unique_org_tag_name constraint (tag name unique per organization). The catch inspects the driver error message for the constraint name and maps it to a 409 CONFLICT with a human-readable message.
Source
Thrown at apps/dokploy/server/api/routers/tag.ts:37
.input(apiCreateTag)
.mutation(async ({ input, ctx }) => {
try {
const newTag = await db
.insert(tags)
.values({
name: input.name,
color: input.color,
organizationId: ctx.session.activeOrganizationId,
})
.returning();
return newTag[0];
} catch (error) {
if (
error instanceof Error &&
error.message.includes("unique_org_tag_name")
) {
throw new TRPCError({
code: "CONFLICT",
message: "A tag with this name already exists in your organization",
});
}
throw new TRPCError({
code: "BAD_REQUEST",
message: `Error creating tag: ${error instanceof Error ? error.message : error}`,
cause: error,
});
}
}),
all: protectedProcedure.query(async ({ ctx }) => {
try {
const organizationTags = await db.query.tags.findMany({
where: eq(tags.organizationId, ctx.session.activeOrganizationId),
orderBy: (tags, { asc }) => [asc(tags.name)],
});View on GitHub (pinned to 546686ea35)
Solutions
- List existing tags (tag.list) and reuse the existing tag instead of creating a new one
- If the name is taken, pick a different name or namespace it (e.g. 'team-a/prod')
- Trim/normalize tag names client-side before submit to avoid accidental duplicates
Example fix
// before
await api.tag.create({ name: 'production' });
// after
const tags = await api.tag.list();
const existing = tags.find(t => t.name === 'production');
if (!existing) await api.tag.create({ name: 'production' }); Defensive patterns
Strategy: validation
Validate before calling
const tags = await api.tag.list();
const name = newName.trim();
if (!tags.some(t => t.name === name)) {
await api.tag.create({ name });
} Try / catch
try { await api.tag.create({ name }); }
catch (e) { if (e.shape?.data?.code === 'CONFLICT') reuseExistingTag(name); else throw e; } Prevention
- Load existing tags before showing the create form
- Trim and normalize names client-side
- Disable submit during in-flight creates to prevent doubles
When it happens
Trigger: Calling tag.create({ name }) with a name that already exists (case-sensitively, per the constraint definition) in the same organization — e.g. creating 'production' when 'production' already exists.
Common situations: Duplicate submit/double click creating the tag twice; teams independently creating tags like 'prod' or 'client-a'; whitespace or casing differences bypassing client-side dedupe but not the DB constraint.
Related errors
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/559308c6be8f434a.
Report an issue: GitHub.