{"record":{"id":"385306e43facb1f9","repo":"paperclipai/paperclip","slug":"upstream-token-missing","errorCode":"upstream_token_missing","errorMessage":"Connection token exchange did not return a token","messagePattern":"Connection token exchange did not return a token","errorType":"http","errorClass":"HttpError","httpStatus":502,"severity":"error","filePath":"server/src/services/tool-access.ts","lineNumber":2154,"sourceCode":"  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    }\n    if (code === \"oauth_challenge\") {\n      return {\n        status: \"error\",\n        message: \"This app needs you to sign in.\",\n        code: \"oauth_challenge\",\n      };\n    }\n    if (code === \"oauth_refresh_missing\") {\n      return {\n        status: \"failed\",\n        message: \"OAuth credentials have expired and need to be reconnected.\",\n        code: \"oauth_refresh_missing\",","sourceCodeStart":2136,"sourceCodeEnd":2172,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/tool-access.ts#L2136-L2172","documentation":"Response-shape guard after token exchange: the broker replied successfully but the payload contains no token field. Treats an unexpected empty body as a protocol failure; the malformed upstream response is at fault.","triggerScenarios":"Thrown at server/src/services/tool-access.ts:1946 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The exchange completed but returned no token. Check the remote service response/logs and re-run the connection flow."],"exampleFix":null,"handlingStrategy":"validation","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"}