{"record":{"id":"5cad37140f9eb05c","repo":"different-ai/openwork","slug":"could-not-prepare-an-openwork-link-response-sta","errorCode":null,"errorMessage":"Could not prepare an OpenWork link (${response.status}).","messagePattern":"Could not prepare an OpenWork link \\((.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/_components/workspace-claim-screen.tsx","lineNumber":211,"sourceCode":"    if (window.sessionStorage.getItem(AUTO_ACCEPT_WORKSPACE_CLAIM_STORAGE_KEY) !== token) return;\n\n    autoClaimAttempted.current = true;\n    window.sessionStorage.removeItem(AUTO_ACCEPT_WORKSPACE_CLAIM_STORAGE_KEY);\n    void handleClaim();\n  }, [claimBusy, claimedOrg, sessionHydrated, token, user]);\n\n  async function createDesktopHandoff(): Promise<string> {\n    const { response, payload } = await requestJson(\n      \"/v1/auth/desktop-handoff\",\n      {\n        method: \"POST\",\n        body: JSON.stringify({ desktopScheme: \"openwork\" }),\n      },\n      12000,\n    );\n\n    if (!response.ok) {\n      throw new Error(getErrorMessage(payload, `Could not prepare an OpenWork link (${response.status}).`));\n    }\n\n    const openworkUrl = getOpenworkUrl(payload);\n    if (!openworkUrl) {\n      throw new Error(\"No OpenWork link was returned.\");\n    }\n\n    return openworkUrl;\n  }\n\n  async function handleOpenDesktop() {\n    setHandoffBusy(true);\n    setHandoffError(null);\n    setHandoffAttempted(true);\n\n    try {\n      window.location.assign(await createDesktopHandoff());\n    } catch (error) {","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/_components/workspace-claim-screen.tsx#L193-L229","documentation":"workspace-claim-screen.tsx throws this when the desktop-handoff request (POST with `desktopScheme: \"openwork\"`, 12s timeout) returns a non-ok HTTP status, using the status code in the message. It is the fallback when the payload has no usable error detail.","triggerScenarios":"The handoff endpoint responds 4xx/5xx (e.g. 401 unauthenticated claim, 500 server error, 504 after the 12-second timeout kills the request upstream) and getErrorMessage cannot extract a message from the body.","commonSituations":"Claim token expired so the server returns 403/404; Den server under load returning 500; reverse proxy timing out before the 12s client timeout; user not yet signed in when clicking 'Open desktop'.","solutions":["Read the interpolated status code and inspect the matching request in the network tab","Refresh the claim page so a fresh claim/session token is used","Retry after confirming the Den server is healthy (server 5xx is often transient)","Check auth: ensure the user completed sign-in before requesting the handoff link"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Preflight: only request the handoff when a session exists\nconst me = await fetch(\"/v1/me\");\nif (!me.ok) {\n  redirectToSignIn();\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const link = await createDesktopHandoff();\n} catch (err) {\n  if (err.message.includes(\"(40\") ) showAuthError(\"Your claim session expired. Refresh the page and try again.\");\n  else showRetryableError(\"Could not prepare an OpenWork link. Please retry in a moment.\");\n}","preventionTips":["Complete sign-in/claim before enabling the 'Open desktop' button","Keep the 12s timeout but add one automatic retry for 5xx before surfacing the error","Check Den server health endpoints when handoff 5xx rates spike","Log the status code server-side with the claim id for faster triage"],"tags":["http","fetch","den-web","desktop-handoff"],"backgroundTag":"api-request-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}