{"record":{"id":"8310e30bbb846cb7","repo":"Dokploy/dokploy","slug":"internal-server-error-8310e3","errorCode":"INTERNAL_SERVER_ERROR","errorMessage":"Failed to move libsql","messagePattern":"Failed to move libsql","errorType":"exception","errorClass":"TRPCError","httpStatus":500,"severity":"critical","filePath":"apps/dokploy/server/api/routers/libsql.ts","lineNumber":446,"sourceCode":"\t\t\t\ttargetEnvironmentId: z.string(),\n\t\t\t}),\n\t\t)\n\t\t.mutation(async ({ input, ctx }) => {\n\t\t\tawait checkServicePermissionAndAccess(ctx, input.libsqlId, {\n\t\t\t\tservice: [\"create\"],\n\t\t\t});\n\n\t\t\tconst updatedLibsql = await db\n\t\t\t\t.update(libsqlTable)\n\t\t\t\t.set({\n\t\t\t\t\tenvironmentId: input.targetEnvironmentId,\n\t\t\t\t})\n\t\t\t\t.where(eq(libsqlTable.libsqlId, input.libsqlId))\n\t\t\t\t.returning()\n\t\t\t\t.then((res) => res[0]);\n\n\t\t\tif (!updatedLibsql) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\",\n\t\t\t\t\tmessage: \"Failed to move libsql\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait audit(ctx, {\n\t\t\t\taction: \"move\",\n\t\t\t\tresourceType: \"service\",\n\t\t\t\tresourceId: updatedLibsql.libsqlId,\n\t\t\t\tresourceName: updatedLibsql.appName,\n\t\t\t});\n\t\t\treturn updatedLibsql;\n\t\t}),\n\trebuild: protectedProcedure\n\t\t.input(apiRebuildLibsql)\n\t\t.mutation(async ({ input, ctx }) => {\n\t\t\tawait checkServicePermissionAndAccess(ctx, input.libsqlId, {\n\t\t\t\tdeployment: [\"create\"],","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/apps/dokploy/server/api/routers/libsql.ts#L428-L464","documentation":"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'.","triggerScenarios":"Moving a database with a stale/deleted libsqlId, targeting a nonexistent environmentId, or a concurrent delete racing the UPDATE so zero rows return.","commonSituations":"Drag-and-drop move in the UI racing a deletion; environment removed while a move dialog was open.","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()"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const [src, dst] = await Promise.all([\n  api.libsql.findOne.query({ libsqlId }),\n  api.environment.findOne.query({ environmentId }),\n]);\nif (!src || !dst) throw new Error(\"verify both ids before moving\");","typeGuard":null,"tryCatchPattern":"try { await move(); } catch (e) { if (/Failed to move libsql/.test((e as Error).message)) { await refetch(); if (stillExists) retry once; else navigateAway(); } }","preventionTips":["Serialize moves with deletes (lock the resource in the UI)","Validate source and target environment ids client-side"],"tags":["libsql","move","database-update","concurrency","trpc"],"backgroundTag":"database-update-failed","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}