paperclipai/paperclip · error · PaperclipCloudConnectorError

CONNECTOR_CONFIG_INVALID

CONNECTOR_CONFIG_INVALID

Error message

GitHub access token is required to authorize a webhook binding

What it means

setWebhookBinding refuses to activate a GitHub webhook binding (values.active === true) when no GitHub access token is supplied. Activating a binding authorizes Paperclip Cloud to register/deliver webhooks, which requires the token; without it the binding would be non-functional, so CONNECTOR_CONFIG_INVALID is thrown.

Source

Thrown at server/src/services/paperclip-cloud-connector.ts:423

        values.companyId,
        profile,
      );
    },
    async revoke(values: { subject: string; companyId: string; profile?: PaperclipCloudConnectorProfileId; token: string }) {
      await call("revoke", { ...values, profile: values.profile ?? "gmail.draft" }, { field: "token", value: values.token });
    },
    async setWebhookBinding(values: {
      subject: string;
      companyId: string;
      id: string;
      installationId: string;
      connectionId: string;
      grantId: string;
      active: boolean;
      accessToken?: string;
    }) {
      if (values.active && !values.accessToken) {
        throw new PaperclipCloudConnectorError(
          "GitHub access token is required to authorize a webhook binding",
          "CONNECTOR_CONFIG_INVALID",
        );
      }
      const binding = JSON.stringify({
        id: values.id,
        installationId: values.installationId,
        connectionId: values.connectionId,
        grantId: values.grantId,
        active: values.active,
        ...(values.active ? { accessToken: values.accessToken } : {}),
      });
      await call("webhook-bind", { ...values, profile: "github.code" }, { field: "binding", value: binding });
    },
    async leaseEvents(values: { subject: string; companyId: string }): Promise<{ leaseId: string; events: SealedConnectorEvents["events"] } | null> {
      const response = await call("event-lease", values);
      if (Array.isArray(response.events) && response.events.length === 0) return null;
      if (typeof response.leaseId !== "string") {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Fetch/load the GitHub access token (e.g. via connector claim/openCredentials) and pass it in values.accessToken before activating
  2. If the token was never stored, run the GitHub authorization flow again to obtain one, then call setWebhookBinding
  3. If only deactivating, pass active: false — the token is not required for deactivation
  4. Add a pre-check in the calling code so activation never proceeds without a token

Example fix

// before
await connector.setWebhookBinding({ id, connectionId, grantId, active: true }); // throws

// after
const { accessToken } = await connector.claim({ subject, companyId });
await connector.setWebhookBinding({ id, connectionId, grantId, active: true, accessToken });
Defensive patterns

Strategy: validation

Validate before calling

// guard before calling
function assertBindingActivatable(values: { active: boolean; accessToken?: string }): void {
  if (values.active && !values.accessToken) {
    throw new Error("accessToken required to activate webhook binding");
  }
}

Type guard

function canActivateBinding(v: { active: boolean; accessToken?: string }): v is { active: true; accessToken: string } {
  return !v.active || typeof v.accessToken === "string" && v.accessToken.length > 0;

Try / catch

try {
  await connector.setWebhookBinding(values);
} catch (e) {
  if (isPaperclipCloudConnectorError(e) && e.code === "CONNECTOR_CONFIG_INVALID") {
    // acquire a GitHub token via claim/authorization, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling setWebhookBinding with { active: true } and accessToken undefined — e.g. toggling an existing binding active from a stored record that lacks the token, or constructing the values object without the credential available.

Common situations: Caller re-activates a binding persisted without its token (tokens not stored at rest); credential rotation removed the GitHub token before the binding update; code path passes active from config but forgets to pass the token field.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/08afcbf1ca828d8f. Report an issue: GitHub.