{"record":{"id":"4ebd827c262bfb05","repo":"hcengineering/platform","slug":"platform-status-unauthorized","errorCode":"platform.status.Unauthorized","errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"PlatformError","httpStatus":401,"severity":"error","filePath":"packages/integration-client/src/request.ts","lineNumber":82,"sourceCode":"    if (contentLength === '0' || (!contentType.includes('application/json') && !contentType.includes('text/json'))) {\n      return undefined\n    }\n\n    const text = await response.text()\n    if (text.trim() === '') {\n      return undefined\n    }\n\n    try {\n      return JSON.parse(text)\n    } catch (error) {\n      console.warn('Failed to parse JSON response:', text, error)\n      return undefined\n    }\n  } else if (response.status === 202) {\n    return undefined\n  } else if (response.status === 401) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.Unauthorized, {}))\n  } else if (response.status === 403) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))\n  } else if (response.status === 404) {\n    throw new PlatformError(\n      new Status(Severity.ERROR, platform.status.ResourceNotFound, { resource: options.path ?? '' })\n    )\n  } else if (response.status >= 500) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {}))\n  } else {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, { status: response.status }))\n  }\n}\n","sourceCodeStart":64,"sourceCodeEnd":95,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/packages/integration-client/src/request.ts#L64-L95","documentation":"The integration client maps HTTP 401 responses from the integration service to PlatformError with status.Unauthorized and message 'Unauthorized'. It means the request's bearer token was missing, expired, or rejected by the server.","triggerScenarios":"Any request() call where the integration service responds with HTTP status 401.","commonSituations":"Expired or revoked auth token passed as token option; token issued for a different account/workspace; token never passed at all to an endpoint that requires it.","solutions":["Re-authenticate / refresh the token used by the client and retry.","Confirm the token is actually being passed (Authorization: Bearer header) for this request.","Check the token's audience/workspace matches the service you are calling.","If using a refresh callback, ensure it is invoked on 401 before giving up."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (token == null || token === '') throw new Error('Auth token required for integration client')","typeGuard":"function isUnauthorized (err: unknown): err is PlatformError {\n  return err instanceof PlatformError && (err.status.code as number) === platform.status.Unauthorized\n}","tryCatchPattern":"try {\n  await client.request(...)\n} catch (err) {\n  if (isUnauthorized(err)) {\n    await refreshToken()\n    return client.request(...) // retry once with fresh token\n  }\n  throw err\n}","preventionTips":["Refresh tokens proactively before expiry, not only on 401.","Always pass the token option for authenticated endpoints.","Verify token audience/workspace matches the target service."],"tags":["auth","unauthorized","http-401","token"],"backgroundTag":"unauthorized-401","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}