Dokploy/dokploy · error · TRPCError

FORBIDDEN

FORBIDDEN

Error message

You are not allowed to access this environment

What it means

Thrown by environmentRouter.findOne when the fetched environment belongs to a different organization than the caller's active session organization. This is an ownership boundary check that runs before any role/permission logic.

Source

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

				if (error instanceof TRPCError) {
					throw error;
				}
				throw new TRPCError({
					code: "BAD_REQUEST",
					message: `Error creating the environment: ${error instanceof Error ? error.message : error}`,
					cause: error,
				});
			}
		}),

	one: protectedProcedure
		.input(apiFindOneEnvironment)
		.query(async ({ input, ctx }) => {
			const environment = await findEnvironmentById(input.environmentId);
			if (
				environment.project.organizationId !== ctx.session.activeOrganizationId
			) {
				throw new TRPCError({
					code: "FORBIDDEN",
					message: "You are not allowed to access this environment",
				});
			}

			if (ctx.user.role !== "owner" && ctx.user.role !== "admin") {
				const { accessedEnvironments, accessedServices } =
					await findMemberByUserId(
						ctx.user.id,
						ctx.session.activeOrganizationId,
					);

				if (!accessedEnvironments.includes(environment.environmentId)) {
					throw new TRPCError({
						code: "FORBIDDEN",
						message: "You are not allowed to access this environment",
					});
				}

View on GitHub (pinned to 546686ea35)

Solutions

  1. Verify the environmentId belongs to the currently active organization
  2. Switch the active organization in the client to the one owning the environment
  3. Re-fetch the environment list for the active org to get valid IDs
Defensive patterns

Strategy: type-guard

Type guard

function isCrossOrgForbidden(e: unknown): boolean {
  return e instanceof TRPCClientError && e.data?.code === 'FORBIDDEN'
    && /not allowed to access this environment/.test(e.message);
}

Try / catch

catch (e) { if (isCrossOrgForbidden(e)) refetchEnvironments(); else throw e; }

Prevention

When it happens

Trigger: Calling environment.one with an environmentId whose project.organizationId differs from ctx.session.activeOrganizationId — e.g. copying an environmentId from another org, or having the wrong organization switched active in the UI.

Common situations: User has multiple organizations and the active one is switched while a stale environment page is open; environmentId leaked across organizations via shared links or bookmarks.

Related errors


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