{"record":{"id":"4605bc6d6e5572c2","repo":"different-ai/openwork","slug":"workspace-endpoint-unavailable-for-selectedid-4605bc","errorCode":null,"errorMessage":"Workspace endpoint unavailable for ${selectedId}.","messagePattern":"Workspace endpoint unavailable for (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/shell/settings-route.tsx","lineNumber":660,"sourceCode":"          }\n        : emptyWorkspaceDisplay,\n    [emptyWorkspaceDisplay, selectedWorkspace],\n  );\n  const workspaceServerClientResolver = useMemo(\n    () => createWorkspaceServerClientResolver({ baseUrl, token }),\n    [baseUrl, token],\n  );\n  const workspaceSelectionCommitRef = useRef<(workspaceId: string) => Promise<void>>(async () => undefined);\n  workspaceSelectionCommitRef.current = async (workspaceId) => {\n    await commitRouteWorkspaceSelection({\n      workspaceId,\n      desktopRuntime: isDesktopRuntime(),\n      setDesktopSelected: workspaceSetSelected,\n      setDesktopRuntimeActive: workspaceSetRuntimeActive,\n      activateWorkspace: async (selectedId) => {\n        const workspace = workspacesRef.current.find((item) => item.id === selectedId) ?? null;\n        const endpoint = workspaceServerClientResolver(workspace);\n        if (!endpoint) throw new Error(`Workspace endpoint unavailable for ${selectedId}.`);\n        if (workspace?.workspaceType === \"local\" && serverActiveWorkspaceIdRef.current === selectedId) return;\n        await endpoint.client.activateWorkspace(endpoint.workspaceId, { persist: true });\n        if (workspace?.workspaceType === \"local\") serverActiveWorkspaceIdRef.current = selectedId;\n      },\n    });\n  };\n  const selectedWorkspaceEndpoint = useWorkspaceServerClient(selectedWorkspace, { baseUrl, token });\n  const opencodeBaseUrl = selectedWorkspaceEndpoint?.opencodeBaseUrl ?? \"\";\n\n  routeStateRef.current = {\n    activeClient,\n    providerBaseUrl: opencodeBaseUrl,\n    selectedWorkspaceId,\n    selectedWorkspaceRoot,\n    selectedWorkspaceType: selectedWorkspace?.workspaceType ?? \"local\",\n    runtimeWorkspaceId: selectedWorkspace?.id ?? null,\n    openworkServerClient: openworkClient,\n    selectedWorkspaceOpenworkClient: openworkClient,","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/shell/settings-route.tsx#L642-L678","documentation":"The settings route's activateWorkspace callback resolves a workspace-scoped server endpoint via workspaceServerClientResolver. resolveWorkspaceEndpoint returns null when the local server handle (baseUrl/token) is missing or the workspace cannot be mapped to an endpoint, so the code throws before calling endpoint.client.activateWorkspace.","triggerScenarios":"Activating a workspace in Settings when the local OpenWork server handle has no baseUrl/token (server stopped or reconnecting) and the workspace has no resolvable remote endpoint, or the workspace entry itself is missing/stale in the local list (workspacesRef.current lookup returns null and no endpoint can be derived).","commonSituations":"Server restarted and handle not yet rehydrated; workspace forgotten on server but cached in UI; local server token rotated so the resolver cache key invalidates to null.","solutions":["Reconnect/restart the OpenWork server so a valid LocalServerHandle (baseUrl+token) exists, then retry activation.","Refresh the workspace list so workspacesRef.current contains the workspace and a valid endpoint can be resolved.","Check resolveWorkspaceEndpoint inputs (workspace id, type, remote baseUrl) for the failing workspace."],"exampleFix":"// before\nconst endpoint = workspaceServerClientResolver(workspace);\nif (!endpoint) throw new Error(`Workspace endpoint unavailable for ${selectedId}.`);\n// after\nconst endpoint = workspaceServerClientResolver(workspace);\nif (!endpoint) { await reconnectLocalServer(); endpoint = workspaceServerClientResolver(workspace); }\nif (!endpoint) throw new Error(`Workspace endpoint unavailable for ${selectedId}.`);","handlingStrategy":"type-guard","validationCode":"const workspace = workspacesRef.current.find((i) => i.id === selectedId);\nif (!workspace) return; // nothing to activate\nconst endpoint = workspaceServerClientResolver(workspace);\nif (!endpoint) await reconnectLocalServer();","typeGuard":"function isResolvedEndpoint(e: ReturnType<WorkspaceServerClientResolver>): e is NonNullable<ReturnType<WorkspaceServerClientResolver>> {\n  return e !== null && typeof e.client?.activateWorkspace === \"function\";\n}","tryCatchPattern":"try {\n  await activateWorkspace(selectedId);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"Workspace endpoint unavailable\")) {\n    await refreshWorkspaceList();\n  } else throw e;\n}","preventionTips":["Keep the LocalServerHandle (baseUrl+token) hydrated before enabling activation.","Refresh the workspace list after server restarts so the resolver cache is valid.","Disable activation buttons while the resolver returns null.","Log resolver-null causes (missing token vs missing workspace) to speed diagnosis."],"tags":["workspace-activation","server-endpoint","null-endpoint"],"backgroundTag":"workspace-endpoint-unresolved","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}