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

  1. List existing tags (tag.list) and reuse the existing tag instead of creating a new one
  2. If the name is taken, pick a different name or namespace it (e.g. 'team-a/prod')
  3. 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

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.