{"record":{"id":"a4654707393b0459","repo":"different-ai/openwork","slug":"getinstallconfigerrormessage-payload-response-sta-a46547","errorCode":null,"errorMessage":"getInstallConfigErrorMessage(payload, response.status)","messagePattern":"getInstallConfigErrorMessage\\(payload, response\\.status\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/_components/join-org-success.tsx","lineNumber":163,"sourceCode":"\n  async function handleGetApp() {\n    setInstallBusy(true);\n    setActionError(null);\n\n    try {\n      const installPageUrl = await createOrganizationInstallLink(organizationId, false);\n      const token = installTokenFromPageUrl(installPageUrl);\n      if (!token) {\n        throw new Error(\"The install link response was incomplete.\");\n      }\n\n      const { response, payload } = await requestJson(\n        `/v1/install-config?token=${encodeURIComponent(token)}`,\n        { method: \"GET\" },\n        12000,\n      );\n      if (!response.ok) {\n        throw new Error(getInstallConfigErrorMessage(payload, response.status));\n      }\n\n      const apiUrl = installerApiUrlFromConfig(payload);\n      if (!apiUrl) {\n        throw new Error(\"This install link returned incomplete setup details.\");\n      }\n\n      const platform = detectedInstallPlatform(detected) ?? \"mac-arm64\";\n      const href = buildInstallDownloadHref(apiUrl, platform, token);\n      setDownloadHref(href);\n      startInstallerDownload(href);\n    } catch (error) {\n      setActionError(error instanceof Error ? error.message : \"Could not prepare your download.\");\n    } finally {\n      setInstallBusy(false);\n    }\n  }\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/_components/join-org-success.tsx#L145-L181","documentation":"In the same handleGetApp flow, once /v1/install-config responds non-ok, the code throws getInstallConfigErrorMessage(payload, response.status): 404 maps to the expired/replaced-link message, otherwise the server's error message or \"Could not load this install link (<status>)\". Unlike install-screen.tsx, there is no special-case for unauthenticated 401 here.","triggerScenarios":"Non-ok status from GET /v1/install-config?token=... in the join-org flow: 404 (token expired/rotated), 400 (bad token), 401 (invalid token — not specially handled here), 5xx (server error).","commonSituations":"The freshly minted install link expired before the user clicked through; Den API restarted with rotated link secrets; transient 5xx during a deploy.","solutions":["For 404: click 'Get app' again to mint a new install link (the old token is dead), or get one from the Members page.","For 5xx: retry and check Den server logs.","Compare with install-screen.tsx handling: add a 401 special case here if unauthenticated users should be told to sign in."],"exampleFix":"// before\nif (!response.ok) throw new Error(getInstallConfigErrorMessage(payload, response.status));\n// after (optional 401 handling)\nif (!response.ok) {\n  if (response.status === 401) throw new Error(\"Sign in to your Den portal to install OpenWork.\");\n  throw new Error(getInstallConfigErrorMessage(payload, response.status));\n}","handlingStrategy":"retry","validationCode":"// token was just extracted; validate before the network call\nif (!hasInstallToken(token)) throw new Error(\"Install token missing\");\n// optional pre-flight\n// const res = await fetch(`/v1/install-config?token=${encodeURIComponent(token)}`, { method: \"HEAD\" });","typeGuard":null,"tryCatchPattern":"try {\n  await handleGetApp(orgId);\n} catch (err) {\n  if (err.message.includes(\"expired or was replaced\")) {\n    mintNewInstallLinkAndRetry(orgId); // 404: old token is dead\n  } else if (/\\(5\\d\\d\\)/.test(err.message)) {\n    retryWithBackoff();\n  } else throw err;\n}","preventionTips":["Use install links promptly; tokens can be rotated by regeneration.","Encode the token with encodeURIComponent in the query string.","Add the same 401 sign-in special case used in install-screen.tsx for consistent UX."],"tags":["http","install","den","expired-link"],"backgroundTag":"token-expired","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}