Dokploy/dokploy · warning · TRPCError

BAD_REQUEST

BAD_REQUEST

Error message

You cannot create a environment with the name 'production'

What it means

Dokploy reserves the name 'production' at the project level and the create-environment procedure hard-blocks creating an environment literally named 'production' (case-sensitive exact match), throwing BAD_REQUEST. Note this is exact-match: 'Production' or 'production-2' pass this check.

Source

Thrown at apps/dokploy/server/api/routers/environment.ts:50

	environments,
	projects,
} from "@/server/db/schema";

export const environmentRouter = createTRPCRouter({
	create: protectedProcedure
		.input(apiCreateEnvironment)
		.mutation(async ({ input, ctx }) => {
			try {
				await checkEnvironmentCreationPermission(ctx, input.projectId);
				if (IS_CLOUD) {
					await assertEnvironmentLimit(
						ctx.session.activeOrganizationId,
						input.projectId,
					);
				}

				if (input.name === "production") {
					throw new TRPCError({
						code: "BAD_REQUEST",
						message:
							"You cannot create a environment with the name 'production'",
					});
				}

				const environment = await createEnvironment(input);

				await addNewEnvironment(ctx, environment.environmentId);
				await audit(ctx, {
					action: "create",
					resourceType: "environment",
					resourceId: environment.environmentId,
					resourceName: environment.name,
				});
				return environment;
			} catch (error) {
				if (error instanceof TRPCError) {

View on GitHub (pinned to 546686ea35)

Solutions

  1. Use a different name such as 'prod', 'production-eu', or 'Production' (check is exact and case-sensitive)
  2. If the default production environment was deleted accidentally, restore it or use the project's recreate/reset flow rather than re-creating by name

Example fix

// before
await trpc.environment.create.mutate({ name: 'production', projectId });

// after
await trpc.environment.create.mutate({ name: 'prod', projectId });
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED = new Set(['production']);
if (RESERVED.has(name)) name = `${name}-2`;

Type guard

const isReservedEnvName = (name: string) => name === 'production';

Try / catch

try {
  await trpc.environment.create.mutate({ name, projectId });
} catch (e) {
  if (e instanceof TRPCClientError && e.message.includes(\"'production'\")) {
    // pick another name and retry
  }
}

Prevention

When it happens

Trigger: Calling environment.create with input.name === 'production' for any project. Projects already get an implicit production environment, so the name is reserved.

Common situations: Users or scripts trying to recreate the default production environment after deleting it; IaC/terraform-style provisioning that loops over a fixed list of environment names including 'production'.

Understand the failure class

Background: BAD_REQUEST error code: request rejected as invalid (HTTP 400) - causes and fixes across libraries — this error's family across 8 libraries.

Related errors


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/25e20984e8eda293. Report an issue: GitHub.