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
- Use a different name such as 'prod', 'production-eu', or 'Production' (check is exact and case-sensitive)
- 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
- Filter reserved names out of provisioning scripts
- Remember projects already ship a default production environment
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.