{"record":{"id":"7605390b6b15cb12","repo":"different-ai/openwork","slug":"workspace-endpoint-unavailable-for-selectedid","errorCode":null,"errorMessage":"Workspace endpoint unavailable for ${selectedId}.","messagePattern":"Workspace endpoint unavailable for (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/shell/use-workspace-route-state.ts","lineNumber":454,"sourceCode":"    [endpointForWorkspace, mergeFetchedSessionsWithPending],\n  );\n  const reloadWorkspaceSessions = useCallback(async (workspaceId: string): Promise<void> => {\n    const workspace = workspacesRef.current.find((item) => item.id === workspaceId);\n    if (!workspace) return;\n    loadedWorkspaceIdsRef.current.delete(workspaceId);\n    await loadWorkspaceSessionsInBackground([workspace]);\n  }, [loadWorkspaceSessionsInBackground]);\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 = endpointForWorkspace(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\n  const refreshRouteState = useCallback(async (options?: { supersede?: boolean }) => {\n    // Dedupe: if a refresh is already running, skip this call. Fast workspace\n    // switches used to fire 5-6 overlapping refreshRouteState() calls which\n    // each fetched workspaces + sessions for every workspace. That workload\n    // multiplied quickly on the event loop and caused the UI to freeze.\n    // Callers reacting to changed connection info pass `supersede` instead of\n    // resetting the in-flight guard: the running attempt goes stale (its\n    // remaining writes are discarded) rather than racing the new one.\n    const attempt = refreshLifecycleRef.current.begin(options);\n    if (!attempt) return;\n    setLoading(true);","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/shell/use-workspace-route-state.ts#L436-L472","documentation":"Thrown by the activateWorkspace callback wired into the route state when no client/endpoint can be resolved for the workspace being activated. endpointForWorkspace returns null for workspaces lacking a usable connection endpoint, and activation is rejected with a message naming the workspace id.","triggerScenarios":"Selecting/activating a workspace whose endpoint lookup (endpointForWorkspace(workspacesRef.current.find(id))) returns undefined — i.e., the workspace has no remote connection info or local endpoint registered.","commonSituations":"Workspace list contains stale entries after the local server restarted; a remote workspace was created without completing its connection; workspaces state not yet hydrated when activation is triggered programmatically (e.g., navigateToWorkspaceSession deep link).","solutions":["Refresh the workspace list (refreshRouteState) so endpoints are populated before activating.","Re-establish the workspace's connection (save/validate its remote connection) if it is a remote workspace.","Check endpointForWorkspace logic/data for the missing workspace and correct stale entries.","Retry activation after app/server startup completes."],"exampleFix":"// before\nif (!endpoint) throw new Error(`Workspace endpoint unavailable for ${selectedId}.`);\n// after — wait briefly for hydration then retry once\nlet endpoint = endpointForWorkspace(workspace);\nif (!endpoint) {\n  await refreshRouteState();\n  endpoint = endpointForWorkspace(workspacesRef.current.find((item) => item.id === selectedId) ?? null);\n  if (!endpoint) throw new Error(`Workspace endpoint unavailable for ${selectedId}.`);\n}","handlingStrategy":"validation","validationCode":"const workspace = workspacesRef.current.find((item) => item.id === selectedId) ?? null;\nif (workspace && !endpointForWorkspace(workspace)) {\n  await refreshRouteState(); // repopulate endpoints before activating\n}","typeGuard":"function hasEndpoint(w: Workspace | null): boolean {\n  return w != null && endpointForWorkspace(w) != null;\n}","tryCatchPattern":"try {\n  await activateWorkspace(selectedId);\n} catch (error) {\n  if (error.message.startsWith(\"Workspace endpoint unavailable\")) {\n    await refreshRouteState();\n    await activateWorkspace(selectedId); // retry once\n  } else throw error;\n}","preventionTips":["Refresh workspace state after server restarts before accepting activation.","Guard deep-link activation behind workspace list hydration.","Prune stale workspaces whose endpoints can no longer be resolved.","Complete remote-connection setup before surfacing a workspace as activatable."],"tags":["workspace","endpoint","state"],"backgroundTag":"missing-workspace-endpoint","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}