{"record":{"id":"602dd059dcc109ae","repo":"paperclipai/paperclip","slug":"upstream-error","errorCode":"upstream_error","errorMessage":"Connection token exchange failed","messagePattern":"Connection token exchange failed","errorType":"http","errorClass":"HttpError","httpStatus":502,"severity":"error","filePath":"server/src/services/tool-access.ts","lineNumber":2142,"sourceCode":"  } catch {\n    return null;\n  }\n}\n\nfunction isOAuthEndpointRejection(error: unknown): boolean {\n  if (!(error instanceof HttpError)) return false;\n  const code = asRecord(error.details).code;\n  return typeof code === \"string\" && code.endsWith(\"_endpoint_rejected\");\n}\n\nfunction healthFailureHttpStatus(failure: { status: ToolConnectionHealthStatus; code: string }): number {\n  if (failure.status === \"missing_secret\") return 422;\n  if (failure.code === \"composio_api_key_rejected\") return 422;\n  if (failure.code.endsWith(\"_endpoint_rejected\")) return 422;\n  return 502;\n}\n\nfunction sanitizeHttpFailure(error: unknown): { status: ToolConnectionHealthStatus; message: string; code: string } {\n  if (error instanceof ComposioApiError) {\n    return {\n      status: \"error\",\n      message: error.message,\n      code: error.status === 401 || error.status === 403 ? \"composio_api_key_rejected\" : \"composio_request_failed\",\n    };\n  }\n  if (error instanceof HttpError) {\n    const code = asRecord(error.details).code;\n    if (code === \"composio_connected_account_inactive\") {\n      return { status: \"degraded\", message: error.message, code };\n    }\n    if (typeof code === \"string\" && code.startsWith(\"remote_http_\")) {\n      return { status: \"error\", message: error.message, code };\n    }\n    if (isOAuthEndpointRejection(error)) {\n      return { status: \"error\", message: error.message, code: String(code) };\n    }","sourceCodeStart":2124,"sourceCodeEnd":2160,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/tool-access.ts#L2124-L2160","documentation":"Token-exchange failure in the child/derived token flow: the broker's HTTP response was non-2xx. The error carries the upstream code (mapped to credential_revoked when the parent was revoked), status, and request id; the upstream broker rejecting the exchange is at fault.","triggerScenarios":"Thrown at server/src/services/tool-access.ts:1934 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The connection token exchange failed. Verify the connection's credentials and the remote service availability, then retry the connection flow."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}