Dokploy/dokploy · critical · TRPCError
INTERNAL_SERVER_ERROR
INTERNAL_SERVER_ERROR
Error message
Failed to move libsql
What it means
The move-to-environment procedure performs a Drizzle UPDATE ... RETURNING and expects exactly one row back. An empty result (id not matched, concurrent delete, or constraint aborting) triggers INTERNAL_SERVER_ERROR 'Failed to move libsql'.
Source
Thrown at apps/dokploy/server/api/routers/libsql.ts:446
targetEnvironmentId: z.string(),
}),
)
.mutation(async ({ input, ctx }) => {
await checkServicePermissionAndAccess(ctx, input.libsqlId, {
service: ["create"],
});
const updatedLibsql = await db
.update(libsqlTable)
.set({
environmentId: input.targetEnvironmentId,
})
.where(eq(libsqlTable.libsqlId, input.libsqlId))
.returning()
.then((res) => res[0]);
if (!updatedLibsql) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to move libsql",
});
}
await audit(ctx, {
action: "move",
resourceType: "service",
resourceId: updatedLibsql.libsqlId,
resourceName: updatedLibsql.appName,
});
return updatedLibsql;
}),
rebuild: protectedProcedure
.input(apiRebuildLibsql)
.mutation(async ({ input, ctx }) => {
await checkServicePermissionAndAccess(ctx, input.libsqlId, {
deployment: ["create"],View on GitHub (pinned to 546686ea35)
Solutions
- Confirm the libsqlId exists and the target environmentId is valid before moving
- Retry after refreshing state — a concurrent delete is the usual culprit
- Inspect Postgres logs if it persists; the UPDATE may be failing on a constraint not surfaced by .returning()
Defensive patterns
Strategy: retry
Validate before calling
const [src, dst] = await Promise.all([
api.libsql.findOne.query({ libsqlId }),
api.environment.findOne.query({ environmentId }),
]);
if (!src || !dst) throw new Error("verify both ids before moving"); Try / catch
try { await move(); } catch (e) { if (/Failed to move libsql/.test((e as Error).message)) { await refetch(); if (stillExists) retry once; else navigateAway(); } } Prevention
- Serialize moves with deletes (lock the resource in the UI)
- Validate source and target environment ids client-side
When it happens
Trigger: Moving a database with a stale/deleted libsqlId, targeting a nonexistent environmentId, or a concurrent delete racing the UPDATE so zero rows return.
Common situations: Drag-and-drop move in the UI racing a deletion; environment removed while a move dialog was open.
Related errors
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/8310e30bbb846cb7.
Report an issue: GitHub.