paperclipai/paperclip · error · VercelConnectClientError
vercel_connect_request_failed
vercel_connect_request_failed
Error message
vercel_connect_request_failed
What it means
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.
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.
Example fix
// before: token from a different connector than recorded
connectorId: 'conn_old', connectorUid: 'uid_old' // connection record
// after: re-link so the record matches the installed connector
await db.update(toolConnections).set({ externalCredential: { connectorId: 'conn_new', connectorUid: 'uid_new', ... } }) Defensive patterns
Strategy: retry
Validate before calling
// before dispatch: confirm the connection's recorded connector still matches the Vercel-side install
const expected = connection.externalCredential;
if (!expected?.connectorId || !expected?.connectorUid) throw new Error('Connection missing connector identity; re-link Vercel Connect'); Type guard
function tokenMatchesConnector(token: { connector: { id: string; uid: string } }, cred: { connectorId: string; connectorUid: string }): boolean {
return token.connector.id === cred.connectorId && token.connector.uid === cred.connectorUid;
} Try / catch
try {
const headers = await resolveCredentialHeaders(session, connection, grant);
} catch (e) {
if (e instanceof ToolGatewayHttpError && e.code === 'vercel_connect_request_failed' && e.status === 502) {
// transient upstream failure: retry with backoff; if persistent, re-link the connector
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- oauth_refresh_failed
- railway_api_error
- settledInvocation?.errorCode ?? tool_execution_failed
- vercel_connect_unavailable
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/96040c4f3d232690.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/tool-gateway.ts:3889
{
connectionId: connection.id,
grantId: grant.id,
},
);
}
const request = vercelTokenRequest({
credential: connection.externalCredential,
grant,
connectionId: connection.id,
companyId: connection.companyId,
});
try {
const token = await vercelConnect.getToken(request, resolveOptions);
if (
token.connector.id !== connection.externalCredential.connectorId &&
token.connector.uid !== connection.externalCredential.connectorUid
) {
throw new VercelConnectClientError(
"vercel_connect_request_failed",
502,
);
}
await db
.update(connectionGrants)
.set({
externalCredential: vercelGrantReference({
credential: connection.externalCredential,
token,
subjectId: grant.externalCredential?.subjectId,
verifiedAt: new Date(options.now?.() ?? Date.now()),
}),
status: "active",
revokedAt: null,
updatedAt: new Date(options.now?.() ?? Date.now()),
})
.where(View on GitHub (pinned to 3f1d897a7c)