{"record":{"id":"5b070a38c7e33250","repo":"theonedev/onedev","slug":"workspace-server-not-found","errorCode":null,"errorMessage":"Workspace server not found","messagePattern":"Workspace server not found","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/workspace/DefaultWorkspaceService.java","lineNumber":854,"sourceCode":"\t\tupdate(workspace);\n\t\tlogService.flush(workspace.getLoggingSupport());\n\t\tlistenerRegistry.post(new WorkspaceInactive(workspace));\n\t}\n\n\t@Override\n\tpublic File getLogFile(Long projectId, Long workspaceNumber) {\n\t\tvar logDir = projectService.getSubDir(projectId, WORKSPACE_LOGS_DIR);\n\t\treturn new File(logDir, workspaceNumber.toString());\n\t}\n\n\t@Sessional\n\t@Override\n\tpublic String openShell(Workspace workspace, String label, @Nullable String command,\n\t\t\t\t\t\t\t @Nullable ShellOutputCallback outputCallback) {\n\t\tvar workspaceId = workspace.getId();\n\t\tvar server = workspaceServers.get(workspaceId);\n\t\tif (server == null)\n\t\t\tthrow new ExplicitException(\"Workspace server not found\");\n\t\tvar shellId = clusterService.runOnServer(server, new ClusterTask<String>() {\n\n\t\t\t@Override\n\t\t\tpublic String call() throws Exception {\n\t\t\t\tvar runtime = workspaceRuntimes.get(workspaceId);\n\t\t\t\tif (runtime == null)\n\t\t\t\t\tthrow new ExplicitException(\"Workspace runtime not found\");\n\t\t\t\tvar shellIdRef = new AtomicReference<String>(null);\n\t\t\t\tvar shellReady = new CompletableFuture<String>();\n\t\t\t\tvar firstOutputSeen = new AtomicBoolean(false);\n\t\t\t\tshellIdRef.set(runtime.openShell(new Terminal() {\n\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic void onShellOutput(String base64Data) {\n\t\t\t\t\t\tvar shellId = shellIdRef.get();\n\t\t\t\t\t\tif (shellId != null) {\n\t\t\t\t\t\t\t// Use runOnAllServers instead of submitToAllServers to preserve output order\n\t\t\t\t\t\t\tclusterService.runOnAllServers(newHandleShellOutputTask(workspaceId, shellId, base64Data));","sourceCodeStart":836,"sourceCodeEnd":872,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/workspace/DefaultWorkspaceService.java#L836-L872","documentation":"Thrown by DefaultWorkspaceService.openShell() when workspaceServers has no entry for the workspace id. In a cluster, a running workspace lives on exactly one server; that mapping is missing, so the shell request cannot be routed. This means the workspace is not running (or its server registration was lost), not that the workspace entity is absent.","triggerScenarios":"Calling workspaceService.openShell(workspace, label, command, callback) while the workspace has no active server assignment — e.g. workspace stopped, server restarted, or cluster state desynchronized.","commonSituations":"Opening a terminal for a workspace that already terminated; a cluster failover removed the server mapping; calling openShell from a node different from the one hosting the workspace without routing; stale UI tab pointing at a dead workspace.","solutions":["Check the workspace is running and retry after it reaches running state.","Stop and recreate/restart the workspace to rebuild the server mapping.","Verify cluster health — re-register the workspace server if the node was restarted.","Guard the UI/action so shell access is only offered for running workspaces."],"exampleFix":"// before\nString shellId = workspaceService.openShell(workspace, \"term\", null, cb);\n// after\nif (workspace.getStatus() == WorkspaceStatus.RUNNING) {\n    String shellId = workspaceService.openShell(workspace, \"term\", null, cb);\n} else {\n    throw new ExplicitException(\"Workspace is not running\");\n}","handlingStrategy":"validation","validationCode":"// Java\nif (workspace.getStatus() != WorkspaceStatus.RUNNING)\n    throw new ExplicitException(\"Workspace must be running to open a shell\");","typeGuard":null,"tryCatchPattern":"try { workspaceService.openShell(workspace, label, null, cb); } catch (ExplicitException e) { if (e.getMessage().contains(\"server not found\")) restartWorkspace(workspace); }","preventionTips":["Only expose shell UI for RUNNING workspaces","Handle cluster failover by re-checking workspace state","Refresh stale UI sessions before issuing workspace commands"],"tags":["onedev","workspace","cluster","state-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}