{"record":{"id":"6f9672411115fdec","repo":"different-ai/openwork","slug":"openwork-workspace-discovery-failed-response-st","errorCode":null,"errorMessage":"OpenWork workspace discovery failed (${response.status} ${response.statusText || \"HTTP error\"})","messagePattern":"OpenWork workspace discovery failed \\((.+?) (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/workspace-store.mjs","lineNumber":745,"sourceCode":"    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), 8_000);\n    const headers = new Headers();\n    const bearerToken = String(token ?? \"\").trim();\n    const hostAuthToken = String(hostToken ?? \"\").trim();\n    if (bearerToken) headers.set(\"Authorization\", `Bearer ${bearerToken}`);\n    if (hostAuthToken) headers.set(\"X-OpenWork-Host-Token\", hostAuthToken);\n\n    try {\n      const electron = await import(\"electron\").catch(() => null);\n      const fetcher = typeof electron?.net?.fetch === \"function\" ? electron.net.fetch.bind(electron.net) : fetch;\n      const response = await fetcher(url, {\n        headers,\n        signal: controller.signal,\n        credentials: \"omit\",\n        cache: \"no-store\",\n      });\n      if (!response.ok) {\n        throw new Error(`OpenWork workspace discovery failed (${response.status} ${response.statusText || \"HTTP error\"})`);\n      }\n      return await response.json();\n    } finally {\n      clearTimeout(timeout);\n    }\n  }\n\n  async function discoverOpenworkWorkspace({ hostUrl, token, hostToken, directory }) {\n    const list = await fetchOpenworkWorkspaceList(hostUrl, token, hostToken);\n    return selectOpenworkWorkspaceForConnection(list, directory);\n  }\n\n  function normalizeWorkspaceEntry(input) {\n    return {\n      id: String(input.id),\n      name: String(input.name ?? \"Workspace\"),\n      path: String(input.path ?? \"\"),\n      preset: String(input.preset ?? \"starter\"),","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/workspace-store.mjs#L727-L763","documentation":"createWorkspaceStore performs an HTTP discovery request against an OpenWork server to find workspaces. If the response is not ok (non-2xx), it throws an error embedding the HTTP status and statusText (falling back to \"HTTP error\"). The request includes a timeout controller, credentials omitted, and no caching.","triggerScenarios":"Any non-ok status from the discovery endpoint: 401/403 for bad or expired tokens, 404 for wrong URL path, 5xx from a broken server, 502/504 from a reverse proxy in front of the server.","commonSituations":"openworkHostUrl misconfigured (wrong port or path), stale openworkToken after server restart, server down while a proxy returns 502, DNS pointing at the wrong host.","solutions":["Read the status in the message: 401/403 → refresh the OpenWork token; 404 → fix the base URL; 5xx → check server logs.","Verify the configured OpenWork server URL is reachable: curl -i <hostUrl>/<discovery-path> with the same headers.","Confirm the token/host pair matches the server (host restarts can invalidate tokens)."],"exampleFix":"// before\nopenworkHostUrl: \"https://den.example.com\"  // 404: API lives under /api\n// after\nopenworkHostUrl: \"https://den.example.com/api\"","handlingStrategy":"retry","validationCode":"const url = new URL(discoveryPath, openworkHostUrl);\nif (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n  throw new Error(`Invalid OpenWork host URL: ${openworkHostUrl}`);\n}\n// optionally pre-flight:\n// const res = await fetch(url, { method: \"HEAD\" }); if (!res.ok) ...","typeGuard":null,"tryCatchPattern":"try {\n  return await discoverWorkspaces({ hostUrl, token });\n} catch (err) {\n  const m = /discovery failed \\((\\d+)/.exec(err.message);\n  const status = m ? Number(m[1]) : 0;\n  if (status >= 500 || status === 0) return retryWithBackoff();\n  if (status === 401 || status === 403) throw new Error(\"Refresh your OpenWork token.\");\n  throw err;\n}","preventionTips":["Validate the server URL (scheme, port, path) before saving it in settings.","Rotate tokens on server restarts; surface 401 as a sign-in prompt.","Add a health-check ping to the server before workspace discovery."],"tags":["network","http","server","configuration"],"backgroundTag":"http-request-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}