paperclipai/paperclip · error

GitHub could not update this App's webhook (HTTP ${response.

Error message

GitHub could not update this App's webhook (HTTP ${response.status}). Check that the App is active and reconnect.

What it means

Thrown by resyncGitHubAppWebhook when GitHub responds to the webhook-update request with a non-200 HTTP status. The response body is cancelled (never read into memory) because provider error bodies are untrusted, and a generic message including only the status code is thrown. It signals GitHub itself rejected the webhook configuration update for this App.

Source

Thrown at server/src/services/chat-github-webhook-config.ts:736

        "x-github-api-version": "2022-11-28",
      },
      body: JSON.stringify({
        url: input.webhookUrl,
        content_type: "json",
        insecure_ssl: "0",
        secret: input.webhookSecret,
      }),
    });
  } catch {
    // A fetch error can embed request bodies, headers, or a proxy response.
    // Keep it out of endpoint health, the audit log, and the board response.
    throw new Error(
      "GitHub webhook configuration could not be confirmed. Reconnect to retry; repository access was not changed.",
    );
  }
  if (response.status !== 200) {
    await response.body?.cancel().catch(() => undefined);
    throw new Error(
      `GitHub could not update this App's webhook (HTTP ${response.status}). Check that the App is active and reconnect.`,
    );
  }

  // GitHub can echo a masked secret and provider error bodies are untrusted.
  // Read a bounded response and return no provider body to callers or logs.
  let config: Record<string, unknown>;
  const reader = response.body?.getReader();
  try {
    if (!reader) throw new Error("Missing webhook configuration response");
    const chunks: Uint8Array[] = [];
    let size = 0;
    while (true) {
      const chunk = await reader.read();
      if (chunk.done) break;
      size += chunk.value.byteLength;
      if (size > MAX_CONFIG_RESPONSE_BYTES) {
        throw new Error("Oversized webhook configuration response");

View on GitHub (pinned to 01ad858492)

Solutions

  1. Read the HTTP status in the message: reconnect the GitHub App in the board to refresh credentials.
  2. Check the GitHub App is active and not suspended at https://github.com/organizations/<org>/settings/apps.
  3. If 404, verify the webhook exists on the App settings page and let the reconnect flow recreate it.
  4. If 422, confirm the configured webhookUrl is a valid public HTTPS endpoint and webhookSecret meets GitHub requirements.
  5. Check github.com status for ongoing incidents.
Defensive patterns

Strategy: try-catch

Try / catch

try { await resyncGitHubAppWebhook(input); }
catch (e) {
  const m = /HTTP (\d{3})/.exec(e.message);
  if (m) {
    const status = Number(m[1]);
    if (status === 401 || status === 403) await promptReconnect();
    else if (status >= 500) await retryLater();
  }
}

Prevention

When it happens

Trigger: Any GitHub API response with status != 200 on the webhook config update endpoint: 401 when the App credentials/token are stale, 403 when the App is suspended, 404 when the webhook no longer exists on the App, 422 when the webhook payload is rejected.

Common situations: GitHub App suspended by an org admin; App uninstalled and reinstalled changing its webhook; expired installation/credentials; GitHub-side validation rejecting an updated URL or secret format.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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