Skip to content

fix(e2e): disable rate limiting on the E2E server to stop 429 flakes (BUG-2089)#922

Merged
xarmian merged 1 commit into
mainfrom
fix/e2e-ratelimit-429-bug-2089
Jul 11, 2026
Merged

fix(e2e): disable rate limiting on the E2E server to stop 429 flakes (BUG-2089)#922
xarmian merged 1 commit into
mainfrom
fix/e2e-ratelimit-429-bug-2089

Conversation

@xarmian

@xarmian xarmian commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Problem

The E2E (Playwright) CI job fails deterministically in web/e2e/collab-persistence.spec.ts:

Error: in-page login failed with status 429
  at browserLogin (web/e2e/collab-persistence.spec.ts:56:28)

Server logs:

level=WARN msg="rate limited" ip=127.0.0.1 path=/api/v1/auth/login limiter=auth
POST /api/v1/auth/login status=429

Not a flake — introduced by TASK-2058 (348c8a3d); CI for that PR and its push to main both failed the same way, and every downstream PR since (e.g. #921). main is currently red on E2E.

Root cause

The E2E harness runs the real pad binary with the real rate limiter, and every test shares one loopback IP (127.0.0.1). The auth limiter allows 5 logins/min/IP, burst 5 (internal/server/middleware_ratelimit.go:206). collab-persistence.spec.ts calls browserLogin for two browser clients per test across several tests, blowing past the cap.

Fix

Add a test-only env knob PAD_DISABLE_RATE_LIMITS. When truthy, New() leaves Server.rateLimiters nil — and RateLimit() already treats nil as a pass-through (middleware_ratelimit.go:379), with Stop() and the MCP path already nil-safe. Wired into the Playwright webServer.env; run-pad.mjs spawns the binary with inherited env so it reaches the pad process.

Limiters stay fully active in prod / self-host — the knob is an explicit opt-in only the E2E server sets.

Testing

  • collab-persistence.spec.ts passes locally with the fix (2/2, was failing on 429).
  • New TestRateLimit_DisabledByEnv pins the bypass; existing limiter tests still pass (limiters on when the env is unset).
  • go build ./... green.

Fixes BUG-2089.

https://claude.ai/code/session_015yuBJQYfDj95cgX3DaD8SF

…(BUG-2089)

The E2E harness runs the real pad binary with the real rate limiter, and
every Playwright test shares one loopback IP (127.0.0.1). The auth limiter
(5 logins/min/IP, burst 5) trips as soon as a spec logs in a couple of
browser clients — collab-persistence.spec.ts logs in two per test — so
browserLogin fails with "in-page login failed with status 429". This was
deterministic, not flaky: it failed on TASK-2058's own PR and its push to
main, and on every downstream PR since.

Add a test-only env knob PAD_DISABLE_RATE_LIMITS: when truthy, New() leaves
Server.rateLimiters nil, which RateLimit() already treats as a pass-through
(Stop() and the MCP path are already nil-safe). Wire it into the Playwright
webServer.env; run-pad.mjs spawns the binary with inherited env so it
reaches the pad process. Limiters stay fully active in prod/self-host — the
knob is an explicit opt-in only the E2E server sets.

Verified: collab-persistence.spec.ts passes locally with the fix; the
existing limiter tests still pass (limiters on when the env is unset); new
TestRateLimit_DisabledByEnv pins the bypass.

Claude-Session: https://claude.ai/code/session_015yuBJQYfDj95cgX3DaD8SF
@xarmian xarmian merged commit c8492db into main Jul 11, 2026
6 checks passed
@xarmian xarmian deleted the fix/e2e-ratelimit-429-bug-2089 branch July 11, 2026 18:30
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