{"record":{"id":"96040c4f3d232690","repo":"paperclipai/paperclip","slug":"vercel-connect-request-failed","errorCode":"vercel_connect_request_failed","errorMessage":"vercel_connect_request_failed","messagePattern":"vercel_connect_request_failed","errorType":"error_code","errorClass":"VercelConnectClientError","httpStatus":502,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":3889,"sourceCode":"          {\n            connectionId: connection.id,\n            grantId: grant.id,\n          },\n        );\n      }\n      const request = vercelTokenRequest({\n        credential: connection.externalCredential,\n        grant,\n        connectionId: connection.id,\n        companyId: connection.companyId,\n      });\n      try {\n        const token = await vercelConnect.getToken(request, resolveOptions);\n        if (\n          token.connector.id !== connection.externalCredential.connectorId &&\n          token.connector.uid !== connection.externalCredential.connectorUid\n        ) {\n          throw new VercelConnectClientError(\n            \"vercel_connect_request_failed\",\n            502,\n          );\n        }\n        await db\n          .update(connectionGrants)\n          .set({\n            externalCredential: vercelGrantReference({\n              credential: connection.externalCredential,\n              token,\n              subjectId: grant.externalCredential?.subjectId,\n              verifiedAt: new Date(options.now?.() ?? Date.now()),\n            }),\n            status: \"active\",\n            revokedAt: null,\n            updatedAt: new Date(options.now?.() ?? Date.now()),\n          })\n          .where(","sourceCodeStart":3871,"sourceCodeEnd":3907,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L3871-L3907","documentation":"After fetching a token from Vercel Connect, the gateway validates that the returned token's connector matches the connection's externalCredential connectorId/connectorUid. A mismatch (or any non-authorization failure inside the getToken/round-trip path) is raised as a VercelConnectClientError with code 'vercel_connect_request_failed' and status 502, then rethrown as a ToolGatewayHttpError. It means the credential resolved to the wrong (or an unusable) upstream connector.","triggerScenarios":"vercelConnect.getToken returns a token whose connector.id differs from externalCredential.connectorId AND whose connector.uid differs from externalCredential.connectorUid (note the && — matching only one field still passes); or getToken/network throws a generic error that is normalized to code 'vercel_connect_request_failed' with status 502 in the catch block.","commonSituations":"The Vercel Connect credential was re-pointed to a different connector (re-install under another account) while the Paperclip connection still records the old connectorId/uid; Vercel's API is degraded and returns an unexpected envelope; the connector was rotated and uid changed server-side.","solutions":["Re-link the Vercel Connect credential so connection.externalCredential.connectorId/connectorUid match the currently installed connector.","Check Vercel status/API health; if getToken is failing transiently, retry after the upstream recovers.","Verify the token connector match logic: the check uses &&, so a partial mismatch (one field equal) is silently accepted — consider requiring an exact match on both.","Inspect markRemoteConnectionHealth output for the connection; a 502 here marks health 'error' and the connection may need manual repair."],"exampleFix":"// before: token from a different connector than recorded\nconnectorId: 'conn_old', connectorUid: 'uid_old' // connection record\n// after: re-link so the record matches the installed connector\nawait db.update(toolConnections).set({ externalCredential: { connectorId: 'conn_new', connectorUid: 'uid_new', ... } })","handlingStrategy":"retry","validationCode":"// before dispatch: confirm the connection's recorded connector still matches the Vercel-side install\nconst expected = connection.externalCredential;\nif (!expected?.connectorId || !expected?.connectorUid) throw new Error('Connection missing connector identity; re-link Vercel Connect');","typeGuard":"function tokenMatchesConnector(token: { connector: { id: string; uid: string } }, cred: { connectorId: string; connectorUid: string }): boolean {\n  return token.connector.id === cred.connectorId && token.connector.uid === cred.connectorUid;\n}","tryCatchPattern":"try {\n  const headers = await resolveCredentialHeaders(session, connection, grant);\n} catch (e) {\n  if (e instanceof ToolGatewayHttpError && e.code === 'vercel_connect_request_failed' && e.status === 502) {\n    // transient upstream failure: retry with backoff; if persistent, re-link the connector\n  }\n  throw e;\n}","preventionTips":["Re-link the Vercel Connect credential whenever the connector is reinstalled or rotated so connectorId/uid stay current.","Retry 502s with exponential backoff before marking the connection unhealthy.","Watch the && connector-match logic: prefer strict equality on both id and uid to catch partial drift."],"tags":["vercel-connect","upstream","credential-mismatch","http-502"],"backgroundTag":"upstream-api-error","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}