#17615·vercel

@vercel/connect: getConnectorMetadata returns the full connector object, not the declared ConnectorMetadata subset

Author: jfonturbelCreated Sep 15, 2026Updated Sep 15, 2026

Summary

getConnectorMetadata() is typed Promise<ConnectorMetadata>, whose doc comment describes it as "the stable, useful subset of the connector object the management APIs return" — nine fields: id, uid, name, type, service, clientUrl?, createdAt, updatedAt, vendor. The implementation spreads the entire response body, so every top-level field the endpoint returns reaches the caller while the type declares nine.

Version

@vercel/connect 2.0.4 and 2.1.0 (dist/connector.js is byte-identical in both).

Code

dist/connector.js:

javascript
const { data, ...rest } = (await response.json());
return { ...rest, vendor: data ?? {} };

Observed

Reading GET /v1/connect/connectors/<connector> — the endpoint the SDK calls — with a CLI user token (key names and value types only):

  • GitHub App connector: 32 top-level keys, 23 of them not declared on ConnectorMetadata, e.g. createdBy, updatedBy, ownerId, ownerTenantId, redirectUri, triggers, triggerDestinations, defaultInstallationId, supportedSubjectTypes, appTokens / userTokens (capability flags). vendor (the API's data), documented as "Vendor-specific public configuration", contains clientId, appId, owner and { "encrypted": true } placeholders for clientSecret, privateKeyPem and webhookSecret.
  • API-key connector: 21 top-level keys, 13 undeclared; vendor.values is an array of { id, value: { encrypted } }.

No secret values are returned — the placeholders only say which secrets a connector holds. I have not compared the payload under a deployment's OIDC token, which is what the SDK uses.

Why it matters

  • Because the type declares nine fields, nothing warns that Response.json(metadata), spreading metadata into a Client Component's props, or logging it ships internal identifiers (user and team ids, redirect URI, trigger configuration) and the list of secrets a connector holds to wherever the object goes.
  • Callers can come to depend on fields the doc comment says are outside the stable subset, and TypeScript won't tell them.

Expected

Return exactly the declared fields — and keep vendor to public configuration, without the secret placeholders — or widen the type and drop the "subset" wording. Picking the fields matches the documented intent.