BugMojoBugMojoBugMojo
FeaturesPricingBlogGuidesAbout
Log inGet started
BugMojoBugMojo

Bug reports that actually help fix bugs — capture, replay, share.

A product of Softech Infra.

Product

  • Features
  • Pricing
  • Get started
  • Log in

Resources

  • Blog
  • Guides
  • Compare
  • Glossary

Company

  • About
  • Contact
  • Privacy
  • Sitemap
  • Engineering
  • Playbooks
© 2026 BugMojo. All rights reserved.
AllGuidesEngineeringPlaybooksCompareGlossaryAlternativesBy roleBug tracking by framework
  1. Home
  2. Blog
  3. Bug reporting by role
  4. Backend Developers
Bug reporting by role

Bug reporting for backend developers — the 2026 playbook

Reproduce client-reported API failures from the exact request the browser sent: 4xx vs 5xx triage, CORS preflight redirects, one-shot Fetch streams, HAR auth headers, and MCP

5 min read·Backend engineering
Isometric line-art of an API request-response loop with a glowing lime 500 status tag on the return path against a dark console canvas

Why Backend Developers need a different playbook

Backend developers rarely see the bug. You see the aftermath: a ticket that says "the API failed," a 4xx or 5xx status, and a client who swears it worked yesterday. RFC 9110 says a 4xx means the client seems to have erred and a 5xx means the server is aware it erred, but the status code never tells you the exact method, path, query string, headers, and request body the browser actually sent. That gap is where most "cannot reproduce" tickets live. The bug you can replay is the bug you can fix.

This is the 2026 playbook for reproducing client-reported API failures from the request and response the browser really sent, not the one you assume it sent. It covers triaging 4xx versus 5xx from a captured payload, why a CORS preflight redirect never reaches your access log, why your own error logger keeps recording an empty response body off a one-shot Fetch stream, and how an AI agent can read the captured call over the Model Context Protocol and draft a failing test before you have finished reading the ticket.

Common pitfalls

The recurring mistakes that get bug reports bounced back — and how to avoid them.

The Postman call passes because it is not the browser call

A hand-written Postman request omits the cookies, the exact Content-Type, and the CORS preflight the browser adds, so the failure vanishes the moment you reproduce by hand. Replay the captured request verbatim, then start subtracting headers one at a time to isolate the one that actually breaks it.

A preflight that gets redirected fails silently in your access log

Because Content-Type: application/json is not CORS-safelisted, the browser sends an OPTIONS preflight first, and preflight requests do not follow redirects. A single HTTP-to-HTTPS or trailing-slash redirect on that OPTIONS kills the call before your real handler logs a line, so the failure is invisible server-side. (MDN, CORS errors.)

Your error logger keeps capturing an empty response body

In the Fetch API a response body is a ReadableStream that can be read only once. If an interceptor already called response.json(), your catch block reads an empty body and logs nothing useful. The code fix is response.clone() before the first read; for an existing failure, a client-side capture records the raw body independently of your app consuming the stream. (MDN, Using Fetch.)

A sanitized HAR cannot replay an auth-dependent 401/403

Chrome DevTools "Export HAR (sanitized)" deliberately excludes Cookie, Set-Cookie, and Authorization headers, so the 401/403 you most need to reproduce arrives in a HAR you cannot replay without manually re-editing the auth headers back in. A capture that knows what to keep beats a hand-collected HAR for auth failures. (Chrome for Developers.)

Real-world examples

What these bugs look like in practice, and how to file them cleanly.

Client sends a different payload than the contract says

What it looks like: The endpoint returns 422 or 400 for one client but never in your tests. The frontend serializes a date, an enum, or a null in a shape your validator rejects, and the server log records only the status, not the offending body.

How to file it: Read the captured request body and replay it as curl. The diff between the assumed payload and the real one is usually the whole bug. Fix the serializer or widen the validator, then add the captured body as a regression fixture so it cannot silently return.

bashbash
# Replay the EXACT failing request the browser sent
curl -i -X POST https://api.example.com/v1/orders \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token-from-capture>' \
  --data-raw '{"items":[{"sku":"A1","qty":"2"}],"placedAt":"2026-06-03T00:00:00Z"}'
# qty is a string, not a number -> server returns 422

Intermittent 500 that no local request reproduces

What it looks like: A 5xx fires for some users and never on your machine. The trigger lives in a specific header, query param, or oversized field the happy-path test never sends, so the unhandled exception stays invisible until a real user hits it.

How to file it: Per RFC 9110 a 5xx means the server knows it erred, so correlate the captured request id and timestamp with your server logs and traces, reproduce with the captured inputs, and convert that into a failing test before you touch the handler.

typescripttypescript
// Vitest/Jest repro built from the captured request
it('returns 200 for the payload that 500'd in prod', async () => {
  const res = await app.inject({
    method: 'POST',
    url: '/v1/orders',
    headers: capturedHeaders, // pulled verbatim from the capture
    payload: capturedBody,
  });
  expect(res.statusCode).toBe(200);
});

Response body is empty in logs but the request clearly failed

What it looks like: Your monitoring shows the failed status but a blank body, so you cannot see the error envelope the API returned. An interceptor consumed the Fetch stream before your logger read it, and the stream cannot be read twice.

How to file it: In code, clone the response before the first read so both the app and the logger get the body. For the bug already in front of you, the client-side network capture preserved the raw response body regardless of what your app did with the stream.

typescripttypescript
// Fetch body is a one-shot stream — clone before reading twice
const res = await fetch(url, init);
const forLog = res.clone();
const data = await res.json();      // app consumes the stream
const raw = await forLog.text();    // logger still sees the body

Workflow comparison

The same bug, filed two ways — with and without a capture tool.

FeatureBugMojoHand-collected HAR / DevTools
Capture the exact failing request + response bodyOne-click, raw body preservedManual Export HAR / Copy as fetch
Keep Cookie / Authorization for a 401/403 replayRetained for replaySanitized HAR strips them
AI agent reads the request via MCP (Claude Code, Cursor)Yes — agent drafts a failing test / curlNo — HAR/screenshot a human must re-key
Pair the network call with DOM replay + consoleCaptured together in one reportSeparate tabs, manually correlated
Server-side traces, exception aggregation, error ratesNot its job — pair with APM/SentryDevTools has none either
Distributed tracing across servicesNo — use OpenTelemetry/DatadogNo
Zero-setup Quick CaptureNo project, no SDKAccount / SDK required
The BugMojo column is highlighted. The closing rows are BugMojo’s core wedge: rrweb session replay, MCP for AI agents, console + network capture, and zero-setup Quick Capture.
Capture your next bug in 15 seconds

BugMojo records the DOM, console, and network — then ships a one-click ticket with the full replay attached. No SDK, no setup.

Try BugMojo free

Frequently asked questions

Frequently asked questions

Sources

  1. RFC 9110: HTTP Semantics — §15.5 (4xx, "client seems to have erred") and §15.6 (5xx, "server is aware that it has erred") — IETF / RFC Editor (2022-06)
  2. Using the Fetch API — response/request bodies are ReadableStreams; cannot read the same body twice; use Response.clone() — MDN Web Docs (2025)
  3. CORS errors — application/json is not safelisted so it triggers an OPTIONS preflight; preflight redirects are not allowed — MDN Web Docs (2025)
  4. Network features reference — Export HAR (sanitized) excludes Cookie, Set-Cookie, and Authorization headers; Copy as fetch / Copy as cURL — Chrome for Developers (2024-07-16)
  5. 2024 State of the API Report — only 37% prioritize API testing; 1% do not test APIs; 5% of teams see API-change failure rates above 25% — Postman (2024-10)
  6. 2025 Developer Survey — 45.2% say debugging AI-generated code is more time-consuming; 66% cite AI "almost right, but not quite" as top frustration — Stack Overflow (2025-12)
  7. Specification 2025-11-25 — Model Context Protocol (open protocol connecting LLM apps to external data/tools via JSON-RPC 2.0) — Model Context Protocol (2025-11-25)
Share:

More roles

Pick another — each guide has its own gotchas, comparison, and fixes.

Product Managers
Product management
QA Engineers
Quality assurance
DevOps & SRE
Operations
Designers
Product design
Developers
Software engineering
Founders
Startups & founders

On this page

  • Why Backend Developers need a different playbook
  • Common pitfalls
  • Real-world examples
  • Workflow comparison