Express.js / Editorial solution guide
Diagnose undefined bodies, query shapes and route migration
Identify whether input disappeared in routing, parser applicability or domain validation before changing every endpoint.
Read-only knowledge base · No public comments
Recognize the symptoms
A handler sees req.body undefined, a string-only service receives an array, a fixed route is captured as an ID, or an old catch-all fails after upgrading. These symptoms belong to different contracts. Preserve the method, safe path pattern, content type and exact package versions with a redacted synthetic request.
Understand the likely causes
- The parser may not match the media type or route scope, a preceding middleware may consume the stream, registration order may favor a broad route, or Express 5 parsing and path grammar may differ from old assumptions. Valid JSON syntax does not establish that its members satisfy the endpoint’s domain contract.
Confirm the request reached the intended route
Check method, mount prefix, fixed-route ordering and parameter names before debugging the body. A /courses/:id route can capture search if registered too early. A nested router may require mergeParams for a parent tenant value, and that inherited value remains untrusted. During Express 5 migration, use named wildcards and brace-based optional portions; test root inclusion deliberately. Compare retained fixtures against the intended schema of paths rather than making a broad catch-all accept every request. A route-not-found response and an object-not-found response should remain distinguishable in internal stage evidence.
Inspect media type, placement and raw-body ownership
express.json runs only under its supported matching policy and does not validate business members. In Express 5, no populated body can remain undefined; do not replace it with {} silently before understanding why. Compare Content-Type, body presence, size bounds and middleware order. A signed callback may need original bytes, so a global JSON parser can consume the stream before the intended verifier. Choose scoped parsing and reject unsupported input under the public contract. Never disable all size checks or log private raw payloads to make the parser appear to work.
Check value shape before conversion
Query parser configuration and repeated keys can produce values other than one string. The local parser below accepts a bounded positive page size only as a complete decimal string. It rejects arrays, partial numeric strings and out-of-range values before a source call. These limits are synthetic and not a recommendation for every API. Express 5 makes req.query a getter and uses a simple default parser, so do not rely on mutating it to store normalized output. Put validated values in a separate domain input object and leave transport input recognizable for diagnosis.
function pageSize(value) {
if (typeof value !== "string" || !/^[1-9][0-9]*$/.test(value)) return null;
const n=Number(value); return Number.isInteger(n) && n <= 20 ? n : null;
}
console.assert(pageSize("10") === 10);
console.assert(pageSize(["10","20"]) === null);
console.assert(pageSize("10rows") === null);
console.assert(pageSize("21") === null);
One scalar fixture passes; array, partial number and excessive size fail. No Express parser is executed.
Repair the failing boundary and retain the old fixture
Move or scope a parser only when evidence shows it missed the route; adjust route order only for a confirmed match conflict. Rewrite old signatures and patterns from the official migration guide with focused tests. Keep identifier, null, absent and unknown-field cases explicit rather than weakening the schema into arbitrary strings. Verify the service receives the exact normalized object and that rejected input cannot write. This guide runs the local page-size calculation only; route grammar, stream consumption, JSON parser errors and real header handling remain unexecuted integration checks.
Verify the fix
Verify one valid request and separate negative cases for wrong method, unsupported media type, absent body, malformed JSON, wrong query shape and invalid domain values. Confirm the exact intended handler and no source write on rejection. Parsing success alone is not sufficient evidence.
Keep it from recurring
- Keep parser scope near its route contract, validate complete value shapes and preserve migration fixtures for fixed routes, wildcards and optional segments. Record Express and middleware versions. Use narrow domain input objects instead of modifying request parser output or mass-assigning it to storage.