{"record":{"id":"1e11f65d16bbaf95","repo":"different-ai/openwork","slug":"invalid-cloud-provider-sync-status-response","errorCode":null,"errorMessage":"Invalid cloud provider sync status response.","messagePattern":"Invalid cloud provider sync status response\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/app/lib/openwork-server.ts","lineNumber":102,"sourceCode":"    !(\"sourceProviderId\" in value) || typeof value.sourceProviderId !== \"string\" ||\n    !(\"name\" in value) || typeof value.name !== \"string\" ||\n    !(\"modelIds\" in value) || !Array.isArray(value.modelIds) || !value.modelIds.every((item) => typeof item === \"string\")\n  ) return null;\n  return {\n    cloudProviderId: value.cloudProviderId,\n    providerId: value.providerId,\n    sourceProviderId: value.sourceProviderId,\n    name: value.name,\n    source: \"source\" in value && typeof value.source === \"string\" ? value.source : null,\n    updatedAt: \"updatedAt\" in value && typeof value.updatedAt === \"string\" ? value.updatedAt : null,\n    modelIds: value.modelIds,\n    importedAt: \"importedAt\" in value && typeof value.importedAt === \"number\" ? value.importedAt : null,\n  };\n}\n\nfunction parseCloudProviderSyncStatus(value: unknown): OpenworkCloudProviderSyncStatus {\n  if (!value || typeof value !== \"object\" || !(\"hasSession\" in value) || typeof value.hasSession !== \"boolean\" || !(\"providers\" in value) || !Array.isArray(value.providers)) {\n    throw new Error(\"Invalid cloud provider sync status response.\");\n  }\n  const providers: CloudImportedProvider[] = [];\n  for (const rawProvider of value.providers) {\n    const provider = parseCloudImportedProvider(rawProvider);\n    if (!provider) throw new Error(\"Invalid cloud provider sync provider response.\");\n    providers.push(provider);\n  }\n  let lastRun: OpenworkCloudProviderSyncStatus[\"lastRun\"] = null;\n  if (\"lastRun\" in value && value.lastRun !== null) {\n    if (!value.lastRun || typeof value.lastRun !== \"object\" || !(\"at\" in value.lastRun) || (typeof value.lastRun.at !== \"string\" && typeof value.lastRun.at !== \"number\")) {\n      throw new Error(\"Invalid cloud provider sync last-run response.\");\n    }\n    const run = parseCloudProviderSyncRun(value.lastRun);\n    lastRun = { at: value.lastRun.at, status: run.status, message: run.message };\n  }\n  // Additive fields (older servers omit them): tolerate absence and malformed\n  // entries instead of failing the whole status read.\n  const reloadPending = \"reloadPending\" in value && value.reloadPending === true;","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/app/lib/openwork-server.ts#L84-L120","documentation":"parseCloudProviderSyncStatus validates the provider sync status response: it must be an object with a boolean `hasSession` and a `providers` array. Anything else — null, HTML, missing fields, non-array providers — throws this error before per-provider parsing begins.","triggerScenarios":"Polling the provider sync status endpoint via createOpenworkServerClient and the body lacks `hasSession` or `providers`, is an error object (e.g. `{error: \"unauthorized\"}`), or is not JSON at all.","commonSituations":"Expired/missing auth token returning an error payload with 200, proxy or captive portal injecting HTML, server schema drift renaming fields, hitting the wrong environment (staging/prod mismatch).","solutions":["Log the raw body and HTTP status before parsing to identify the real payload.","Re-authenticate with the Den server; an unauthorized error body often lacks these fields.","Verify the base URL points at the intended OpenWork Den server/environment.","Diff the response against the current server API schema and update the parser if fields changed."],"exampleFix":"// before: parse blindly\nconst status = parseCloudProviderSyncStatus(await res.json());\n// after: guard status + shape, with a descriptive failure\nif (!res.ok) throw new Error(`Sync status fetch failed (${res.status}): ${await res.text()}`);\nconst body = await res.json();\nconst status = parseCloudProviderSyncStatus(body);","handlingStrategy":"type-guard","validationCode":"const body = await res.json();\nconst looksLikeStatus =\n  body && typeof body === \"object\" &&\n  \"hasSession\" in body && typeof body.hasSession === \"boolean\" &&\n  \"providers\" in body && Array.isArray(body.providers);\nif (!looksLikeStatus) throw new Error(`Sync status payload malformed: ${JSON.stringify(body).slice(0, 200)}`);","typeGuard":"function isSyncStatusPayload(v: unknown): v is { hasSession: boolean; providers: unknown[] } {\n  return (\n    typeof v === \"object\" && v !== null &&\n    \"hasSession\" in v && typeof (v as { hasSession: unknown }).hasSession === \"boolean\" &&\n    \"providers\" in v && Array.isArray((v as { providers: unknown }).providers)\n  );\n}","tryCatchPattern":"try {\n  const status = await client.cloud.providerSync.status();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"Invalid cloud provider sync status response\")) {\n    // shape mismatch: verify auth token and environment URL, then log body\n    await reauthenticateIfExpired();\n  } else throw err;\n}","preventionTips":["Validate HTTP status and content-type before json() parsing.","Handle unauthorized error bodies explicitly instead of feeding them to the shape parser.","Confirm the base URL targets the intended Den environment.","Snapshot real status responses in contract tests to catch schema drift early."],"tags":["validation","api-response","cloud","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}