paperclipai/paperclip · error · GitHubWebhookRecoveryError
github_webhook_recovery_transport
github_webhook_recovery_transport
Error message
github_webhook_recovery_transport
What it means
Thrown when the fetch completed but the AbortController signal was already aborted — i.e. the request raced the timeout (default 25s, or the per-call timeoutMs like 10s/2s in getGitHubRecoveryComment). It carries code github_webhook_recovery_transport, and when uncertainMutation is true (redelivery POST) requestMayHaveBeenAccepted=true because GitHub may still have processed the mutation.
Source
Thrown at server/src/services/chat-github-webhook-config.ts:355
(async () => {
const response = await input.fetch(
`https://api.github.com${input.path}`,
{
method: input.method ?? "GET",
redirect: "error",
signal: controller.signal,
headers: {
accept: "application/vnd.github+json",
authorization: `Bearer ${input.token}`,
"x-github-api-version": "2022-11-28",
...(input.body ? { "content-type": "application/json" } : {}),
},
...(input.body ? { body: input.body } : {}),
},
);
if (controller.signal.aborted) {
await response.body?.cancel().catch(() => undefined);
throw new GitHubWebhookRecoveryError(
"github_webhook_recovery_transport",
null,
null,
input.uncertainMutation === true,
);
}
if (response.status !== (input.expectedStatus ?? 200)) {
await response.body?.cancel().catch(() => undefined);
throw new GitHubWebhookRecoveryError(
"github_webhook_recovery_http",
response.status,
retryDelay(response.headers),
input.uncertainMutation === true &&
(response.status >= 500 || response.status === 408),
);
}
return input.project(response, controller.signal);
})(),View on GitHub (pinned to 01ad858492)
Solutions
- Check https://www.githubstatus.com for a GitHub API incident; wait and retry if degraded.
- Increase the timeout for calls you control by adjusting the timeoutMs passed through (recoveryRequest's callers fix these internally; in your wrapper allow longer budgets).
- For requestGitHubAppWebhookRedelivery, treat transport errors as ambiguous: check delivery status via getGitHubAppWebhookDelivery before re-triggering, since the mutation may have been accepted.
- Retry with backoff for GET endpoints (safe); never blind-retry POST redeliveries.
- Verify network/proxy health and DNS resolution to api.github.com.
Example fix
// before
await requestGitHubAppWebhookRedelivery({ fetch, appToken, deliveryId }); // may throw transport error
// after
try {
await requestGitHubAppWebhookRedelivery({ fetch, appToken, deliveryId });
} catch (e) {
if (e instanceof GitHubWebhookRecoveryError && e.code === "github_webhook_recovery_transport" && e.requestMayHaveBeenAccepted) {
const d = await getGitHubAppWebhookDelivery({ fetch, appToken, deliveryId }); // reconcile before retrying
if (d.redelivery) return; // already redelivered
} else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
function isTransportTimeout(e: unknown): e is GitHubWebhookRecoveryError {
return e instanceof GitHubWebhookRecoveryError && e.code === "github_webhook_recovery_transport";
} Try / catch
try {
await requestGitHubAppWebhookRedelivery({ fetch, appToken, deliveryId });
} catch (e) {
if (e instanceof GitHubWebhookRecoveryError && e.code === "github_webhook_recovery_transport") {
// requestMayHaveBeenAccepted may be true — reconcile, don't blind-retry
const d = await getGitHubAppWebhookDelivery({ fetch, appToken, deliveryId });
if (!d.redelivery) await requestGitHubAppWebhookRedelivery({ fetch, appToken, deliveryId });
return;
}
throw e;
} Prevention
- Check githubstatus.com before running bulk recovery during incidents
- Allow generous timeouts; the library already uses 25s default (2s for token revoke)
- For POST mutations always reconcile state before retrying
- Add backoff between recovery attempts
When it happens
Trigger: GitHub API responding slower than the timeout during a redelivery POST or comment token mint; network stalls/proxy hangs; overload of api.github.com (degraded performance); timeoutMs set too low for a slow environment (e.g. 2s token revocation in getGitHubRecoveryComment timing out regularly).
Common situations: Corporate proxies adding seconds of latency; regional network issues to api.github.com; long redelivery queues on GitHub's side during incidents; containerized CI with slow DNS.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- github_attachment_download_failed
- github_webhook_recovery_invalid_response
- github_webhook_recovery_http
- GitHub webhook configuration is incomplete
- The pause was saved, but stopping could not be verified. Ref
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/838181b24492f6f0.
Report an issue: GitHub.