Desk Clarity

A field guide to everyday digital problems.

Developer tools / Practical guide

Fetch Resolves a 404 Response: Check HTTP Status Before Parsing Success Data

A received HTTP error response can fulfill the fetch promise.

By ON Lab2 min readSources checked November 10, 2026 (KST)

A received HTTP error response can fulfill the fetch promise. Check response.ok or a deliberate accepted-status policy before treating its body as successful application data.

Reproduce in an empty temporary directory

This isolated example creates only fixture data in its working directory or runs local JavaScript. Run it separately from your project so the named files cannot overwrite real work.

const assert = require('node:assert/strict');
async function readSuccess(fetcher) {
  const response = await fetcher();
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}
(async () => {
  // Local fake fetch: no network request is made.
  const fake404 = async () => new Response('{"error":"missing"}', {
    status: 404, headers: {'Content-Type': 'application/json'}
  });
  const response = await fake404();
  assert.equal(response.status, 404);
  await assert.rejects(() => readSuccess(fake404), /HTTP 404/);
  console.log('fulfilled response; explicit HTTP gate rejected');
})().catch(error => { console.error(error); process.exitCode = 1; });

Observed local output

fulfilled response; explicit HTTP gate rejected

What to compare

The fake fetch fulfills with a Response, while the application wrapper rejects that response under its own policy. This isolates the status-check contract without relying on a real server. A network failure is another category: it can reject before a response exists. A body parsing failure is a third category and can occur even with an HTTP success status.

Choose the next action

Check the HTTP status and choose the accepted response shape before parsing. For endpoints that return 204, do not blindly require JSON from an empty body. For error responses, preserve bounded diagnostic details according to the API contract and privacy policy, without consuming the same body twice by accident. Decide which failures are retryable; an application-level 404 is not a reason to repeat a request indefinitely.

Limits and verification

The fixture uses the Node Response implementation and an injected fake, so it does not verify browser CORS, cookies or a particular endpoint. Browser opaque responses also require separate handling; changing to no-cors does not make a readable API response appear. Use a real controlled endpoint test when integrating the wrapper, and report transport, HTTP, parsing and business validation outcomes separately.

Related: Awaiting an Array Map Does Not Await Its Tasks: Aggregate the Returned Promises.

Isolated example executed on macOS on November 10, 2026 (KST), using Bash 3.2, Python 3 for the byte fixture, and Node v26.5.0. Results describe the example, not your application or every runtime version.

Sources & further reading