{"record":{"id":"f6c4bdba91fd5bf5","repo":"Dokploy/dokploy","slug":"unauthorized-f6c4bd","errorCode":"UNAUTHORIZED","errorMessage":"You don't have access to this server.","messagePattern":"You don't have access to this server\\.","errorType":"exception","errorClass":"TRPCError","httpStatus":401,"severity":"error","filePath":"apps/dokploy/server/api/routers/cluster.ts","lineNumber":26,"sourceCode":"import { TRPCError } from \"@trpc/server\";\nimport { quote } from \"shell-quote\";\nimport { z } from \"zod\";\nimport { audit } from \"@/server/api/utils/audit\";\nimport { getLocalServerIp } from \"@/server/wss/terminal\";\nimport { createTRPCRouter, withPermission } from \"../trpc\";\n\nexport const clusterRouter = createTRPCRouter({\n\tgetNodes: withPermission(\"docker\", \"read\")\n\t\t.input(\n\t\t\tz.object({\n\t\t\t\tserverId: z.string().optional(),\n\t\t\t}),\n\t\t)\n\t\t.query(async ({ input, ctx }) => {\n\t\t\tif (input.serverId) {\n\t\t\t\tconst targetServer = await findServerById(input.serverId);\n\t\t\t\tif (targetServer.organizationId !== ctx.session.activeOrganizationId) {\n\t\t\t\t\tthrow new TRPCError({\n\t\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\t\tmessage: \"You don't have access to this server.\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst docker = await getRemoteDocker(input.serverId);\n\t\t\tconst workers: DockerNode[] = await docker.listNodes();\n\t\t\treturn workers;\n\t\t}),\n\n\tremoveWorker: withPermission(\"server\", \"delete\")\n\t\t.input(\n\t\t\tz.object({\n\t\t\t\tnodeId: z.string(),\n\t\t\t\tserverId: z.string().optional(),\n\t\t\t}),\n\t\t)\n\t\t.mutation(async ({ input, ctx }) => {","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/apps/dokploy/server/api/routers/cluster.ts#L8-L44","documentation":"Cluster swarmpool route guard: when a serverId is provided, the target server's organizationId must match the session's activeOrganizationId before a remote Docker client is created. Thrown during read queries that inspect the swarm/node pool.","triggerScenarios":"Querying cluster endpoints with a serverId owned by another organization, or using a stale serverId after the server was reassigned/recreated in a different org.","commonSituations":"Multi-org installs, stale dropdown selection after switching orgs, or scripts with hardcoded serverIds.","solutions":["Verify the serverId belongs to your active organization (list servers first)","Switch active organization to the one that owns the server","Refresh server list to pick a currently-valid serverId"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const servers = await trpc.server.all.query();\nif (input.serverId && !servers.some(s => s.serverId === input.serverId)) {\n  delete input.serverId; // or throw\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Strip stale serverId query params on org switch","Populate server selectors from the live API, not localStorage","Omit serverId when targeting the local web server"],"tags":["dokploy","trpc","cluster","authorization","server-access"],"backgroundTag":"organization-ownership-mismatch","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}