{"record":{"id":"998fa92811e0f92a","repo":"different-ai/openwork","slug":"organization-context-response-was-incomplete","errorCode":null,"errorMessage":"Organization context response was incomplete.","messagePattern":"Organization context response was incomplete\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_providers/org-dashboard-provider.tsx","lineNumber":191,"sourceCode":"\n  async function loadOrgContext(organizationId: string, refreshRoles: boolean) {\n    const path = refreshRoles ? \"/v1/org?refreshRoles=true\" : \"/v1/org\";\n    const { response, payload } = await requestJson(\n      path,\n      { method: \"GET\", headers: { [ORG_SCOPE_HEADER]: organizationId } },\n      12000,\n    );\n    if (!response.ok) {\n      if (response.status === 404) {\n        throw new OrganizationNotFoundError(getErrorMessage(payload, `Failed to load organization (${response.status}).`));\n      }\n\n      throw new Error(getErrorMessage(payload, `Failed to load organization (${response.status}).`));\n    }\n\n    const parsed = parseOrgContextPayload(payload);\n    if (!parsed) {\n      throw new Error(\"Organization context response was incomplete.\");\n    }\n\n    return parsed;\n  }\n\n  async function restoreDisplayedOrganization() {\n    const displayedOrgId = orgContext?.organization.id;\n    if (!displayedOrgId) {\n      return;\n    }\n\n    setRequestOrgScope(displayedOrgId);\n    await setActiveOrganization({ organizationId: displayedOrgId });\n    setOrgDirectory((current) => current.map((entry) => ({ ...entry, isActive: entry.id === displayedOrgId })));\n  }\n\n  async function refreshOrgData() {\n    if (!user) {","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_providers/org-dashboard-provider.tsx#L173-L209","documentation":"loadOrgContext throws this when the response is ok (HTTP 200) but parseOrgContextPayload returns null/falsy — i.e., the server returned a 2xx body that does not match the expected organization-context shape. This is a response-schema/contract mismatch, not an HTTP failure.","triggerScenarios":"den-api deployed with an older/newer /v1/org payload shape than the den-web parser expects; proxy or middleware returning an empty or HTML body with 200 (e.g., a login page injected by a captive portal or misconfigured SSO gateway); truncated responses.","commonSituations":"Version skew between den-web and den-api after a partial deploy; reverse proxy serving a cached or rewritten 200 response; single-org-mode server returning a minimal payload missing expected fields.","solutions":["Log the raw payload at parse time to see what the 200 body actually contains.","Align den-web and den-api versions — deploy both together so the /v1/org schema matches parseOrgContextPayload.","Check the reverse proxy for body-rewriting rules, auth redirects converted to 200, or HTML error pages.","Make parseOrgContextPayload validate with Zod (or similar) so the failure pinpoints the missing field.","Retry once before throwing; transient truncation via proxy is a common cause."],"exampleFix":"// before\nconst parsed = parseOrgContextPayload(payload);\nif (!parsed) throw new Error(\"Organization context response was incomplete.\");\n// after\nconst parsed = OrgContextSchema.safeParse(payload);\nif (!parsed.success) {\n  throw new Error(`Organization context response was incomplete: ${parsed.error.issues.map(i => i.path.join('.')).join(',')}`);\n}","handlingStrategy":"type-guard","validationCode":"// validate the 200 body before use\nconst parsed = OrgContextSchema.safeParse(payload);\nif (!parsed.success) throw new Error(`Incomplete org context: ${parsed.error.message}`);","typeGuard":"function isOrgContext(p: unknown): p is { organization: { id: string; slug: string }; role: string } {\n  const o = p as { organization?: { id?: unknown; slug?: unknown }; role?: unknown } | null;\n  return !!o && typeof o.organization === \"object\" && typeof o.organization?.id === \"string\" && typeof o.organization?.slug === \"string\" && typeof o.role === \"string\";\n}","tryCatchPattern":"try {\n  await loadOrgContext(orgId, false);\n} catch (err) {\n  if (String(err.message).startsWith(\"Organization context response was incomplete\")) {\n    await refreshOrgData(); // resync rather than crash the dashboard\n  } else throw err;\n}","preventionTips":["Validate all API payloads with a schema (Zod) at the boundary.","Deploy den-web and den-api atomically to avoid envelope drift.","Audit reverse proxies for body rewriting or 200-wrapped auth pages.","Include response-shape contract tests against a witness/mock server.","Log the offending payload with the error to speed triage."],"tags":["schema","contract-mismatch","api","den-web"],"backgroundTag":"schema-validation-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}