paperclipai/paperclip · error · GitHubWebhookRecoveryError
github_webhook_recovery_invalid_response
github_webhook_recovery_invalid_response
Error message
github_webhook_recovery_invalid_response
What it means
GitHubWebhookRecoveryError with code github_webhook_recovery_invalid_response is thrown by the invalidResponse() helper whenever a GitHub API response body fails strict validation (wrong JSON shape, oversized body, bad ID/timestamp/URL/enum format). It exists so the recovery layer never trusts malformed provider data and never leaks the raw payload. The message is intentionally generic — the actual offending value is discarded.
Source
Thrown at server/src/services/chat-github-webhook-config.ts:89
this.name = "GitHubWebhookRecoveryError";
}
}
type AppRequest = { fetch: typeof globalThis.fetch; appToken: string };
const GITHUB_DELIVERIES_URL = "https://api.github.com/app/hook/deliveries";
const MAX_DELIVERIES_BYTES = 262_144;
const MAX_DETAIL_BYTES = 1_048_576;
const MAX_RETRY_DELAY_MS = 86_400_000;
const ID_KEYS = new Set([
"id",
"installation_id",
"repository_id",
"number",
"in_reply_to_id",
]);
function invalidResponse(): never {
throw new GitHubWebhookRecoveryError(
"github_webhook_recovery_invalid_response",
);
}
function record(value: unknown): Record<string, unknown> {
if (!value || typeof value !== "object" || Array.isArray(value))
invalidResponse();
return value as Record<string, unknown>;
}
function decimalId(value: unknown): string {
if (
typeof value !== "string" ||
!/^[1-9][0-9]{0,19}$/.test(value) ||
(value.length === 20 && value > "18446744073709551615")
)
invalidResponse();
return value;View on GitHub (pinned to 01ad858492)
Solutions
- Log only the error code (the raw response is intentionally discarded) and re-run the failing call while inspecting the raw HTTP traffic separately (curl or httpx) to see what GitHub actually returned.
- Verify no proxy/firewall is rewriting api.github.com responses; set HTTPS_PROXY correctly or bypass it.
- If a mock server is used in tests, update fixtures to match the strict validators (decimal-string IDs, GitHub ISO timestamps, https callback URL, valid guid, lowercase event names).
- Ensure Node >=24.11 so JSON.parse supplies context.source for lossless ID recovery; upgrade the runtime if on older Node.
- If the failure is persistent on one endpoint, check GitHub's status/changelog for a response-shape change and update the validator deliberately.
Example fix
// before (test fixture that trips validators)
{ "id": 12345678, "delivered_at": "2024-01-01T00:00:00Z", "event": "push", "guid": "not-a-uuid" }
// after
{ "id": "12345678", "delivered_at": "2024-01-01T00:00:00.000Z", "event": "push", "guid": "0f5a1b2c-3d4e-5f60-7182-93a4b5c6d7e8" } Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
function isRecoveryResponseError(e: unknown): e is GitHubWebhookRecoveryError {
return e instanceof GitHubWebhookRecoveryError && e.code === "github_webhook_recovery_invalid_response";
} Try / catch
try {
await listGitHubAppWebhookDeliveries({ fetch, appToken });
} catch (e) {
if (isRecoveryResponseError(e)) {
log.warn("GitHub returned malformed webhook data; not retrying", { code: e.code });
} else throw e;
} Prevention
- Keep GitHub fixtures in tests aligned with the strict validators (string IDs, ISO timestamps, https URLs)
- Monitor GitHub API changelog for response-shape changes
- Bypass or correctly configure proxies that may rewrite api.github.com responses
- Run on Node >=24.11 for lossless JSON.parse source recovery
When it happens
Trigger: Any GitHub webhook-recovery call (listGitHubAppWebhookDeliveries, readGitHubAppWebhookConfig, getGitHubAppWebhookDelivery, getGitHubRecoveryComment) whose response fails a validator: non-object/array body via record(), ID not matching /^[1-9][0-9]{0,19}$/, timestamp not GitHub ISO format, oversized body (content-length or streamed size over the per-endpoint max), invalid guid/redelivery/status_code/event/action, callback URL not https with no query/hash/credentials, bad repo full_name, Link header parse failures in nextCursor.
Common situations: GitHub API behavior changed or a proxy/gateway intercepts api.github.com and returns an HTML error page or a differently-shaped JSON; a corporate MITM proxy truncates the body; a mock/stub test server returns loose fixtures that violate the strict regexes; running on an older Node without JSON.parse context.source so rounded numeric IDs fail decimalId.
Related errors
- GitHub webhook configuration is incomplete
- github_webhook_recovery_invalid_input
- github_webhook_recovery_transport
- github_webhook_recovery_http
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/c45e157059e50b35.
Report an issue: GitHub.