Dokploy/dokploy · error · TRPCError

INTERNAL_SERVER_ERROR

INTERNAL_SERVER_ERROR

Error message

Failed to move compose

What it means

Thrown by the moveCompose tRPC mutation when the Drizzle update()...returning() query for composeTable does not return a row. Returning() normally fails loudly; an empty result means the WHERE clause (composeId) matched no row after the update executed.

Source

Thrown at apps/dokploy/server/api/routers/compose.ts:790

				targetEnvironmentId: z.string(),
			}),
		)
		.mutation(async ({ input, ctx }) => {
			await checkServicePermissionAndAccess(ctx, input.composeId, {
				service: ["create"],
			});

			const updatedCompose = await db
				.update(composeTable)
				.set({
					environmentId: input.targetEnvironmentId,
				})
				.where(eq(composeTable.composeId, input.composeId))
				.returning()
				.then((res) => res[0]);

			if (!updatedCompose) {
				throw new TRPCError({
					code: "INTERNAL_SERVER_ERROR",
					message: "Failed to move compose",
				});
			}

			await audit(ctx, {
				action: "update",
				resourceType: "compose",
				resourceId: input.composeId,
				resourceName: updatedCompose.name,
			});
			return updatedCompose;
		}),

	processTemplate: protectedProcedure
		.input(
			z.object({
				base64: z.string(),

View on GitHub (pinned to 546686ea35)

Solutions

  1. Verify the composeId exists (findComposeById) before calling moveCompose
  2. Refresh the client state/refetch composes after deletions
  3. Wrap the call and treat empty result as NOT_FOUND rather than retrying

Example fix

// before
await api.compose.moveCompose({ composeId, serverId });
// after
const compose = await api.compose.get.byComposeId({ composeId });
if (!compose) throw new Error('Compose no longer exists');
await api.compose.moveCompose({ composeId, serverId });
Defensive patterns

Strategy: validation

Validate before calling

const compose = await findComposeById(composeId);
if (!compose) throw new Error('Compose not found');

Prevention

When it happens

Trigger: Calling moveCompose with a composeId that does not exist in the compose table, or that was concurrently deleted between authorization and the update.

Common situations: Stale UI holding a deleted compose's ID; race with a simultaneous delete; passing an ID from a different environment/database.

Related errors


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