Skip to content

Accept webhooks up to GitHub's 25 MB - #531

Merged
jarstelfox merged 2 commits into
masterfrom
webhook-body-limit
Oct 20, 2026
Merged

jarstelfox merged 2 commits into
masterfrom
webhook-body-limit

Conversation

@jarstelfox

@jarstelfox jarstelfox commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

🤖

Every POST shared one 1 MB body limit (maxPostSize in app.js), so a webhook for a big PR got a 413 and its update was dropped until the hourly reconcile caught it. Prod's logs:

Log PayloadTooLargeError
Oct 12 to 13 47
Oct 16 to 20 50

That's about a dozen dropped updates a day. GitHub sends webhook payloads up to 25 MB.

  • /hooks now parses JSON and form bodies up to 25 MB. The board and the API keep 1 MB.
  • The parsers move to lib/body-parsers.js, so a test can mount them without starting the app. The hook parsers run first; body-parser skips a body that's already parsed, so the global ones leave hook requests alone.
  • The route is public (GitHub has to reach it), so its secret, which is in the query string, is now checked before the body is read. Without the secret, a request gets the same 401 without the server buffering up to 25 MB first. This was a review finding.
  • test/body-parsers.test.js posts a 2 MB body: JSON and form-encoded to /hooks/main get a 200, JSON to another route still gets a 413, and a hook without the secret gets a 401.

🤖 Generated with Claude Code

jarstelfox and others added 2 commits October 20, 2026 14:20
Every POST shared one 1 MB body limit, so a webhook for a big PR (a long
body, many labels, a large push) got a 413 and its update was dropped
until the hourly reconcile. Prod logged 47 of these on Oct 12-13 and 50
between Oct 16 and 20, about a dozen a day.

The webhook route now parses up to GitHub's 25 MB limit; the board and
the API keep 1 MB. The parsers move to lib/body-parsers.js so a test can
mount them without starting the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review: the route is public, and the secret was checked only after
parsing, so anyone could make the server buffer 25 MB per request. The
secret is in the query string, so it can be checked first; a request
without it gets the same 401 before any of its body is read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jarstelfox
jarstelfox merged commit 0f387f1 into master Oct 20, 2026
1 check passed
@jarstelfox
jarstelfox deleted the webhook-body-limit branch October 20, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant