Skip to content

fix(cli): #1766 return a 404 when a develop page file is deleted while the server runs - #1773

Open
jstockdi wants to merge 3 commits into
ProjectEvergreen:masterfrom
Battle-Creek-LLC:bug/issue-1766-develop-deleted-page-404
Open

fix(cli): #1766 return a 404 when a develop page file is deleted while the server runs#1773
jstockdi wants to merge 3 commits into
ProjectEvergreen:masterfrom
Battle-Creek-LLC:bug/issue-1766-develop-deleted-page-404

Conversation

@jstockdi

@jstockdi jstockdi commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Related Issue

Resolves #1766

Documentation

No documentation changes. This corrects an HTTP status code in greenwood develop; the documented behaviour is unchanged.

Summary of Changes

Deleting a page file while the dev server is running returned a 500 with an empty body, plus a raw ENOENT stack in the terminal, where a 404 is correct.

The page graph is generated once at startup, so a deleted page's node is still present. shouldServe in the standard HTML resource plugin still matches the route, serve then reaches an unguarded fs.readFile, and the resulting ENOENT is swallowed by the catch-all in lifecycles/serve.js, which sets a 500. Restarting develop makes the same route correctly 404.

The fix guards that one read: in develop, an ENOENT returns a 404 response; any other error still throws so real failures are not masked.

The develop gate is load-bearing rather than cosmetic. lifecycles/prerender.js calls plugin.serve() on every resource plugin and does not check response.ok, so an ungated 404 here is swallowed during greenwood build: a page deleted between graph generation and prerender produced exit 0, a generated page... log line, and an empty public/<route>/index.html. Greenwood's convention for a missing page file at build time is a hard failure (lifecycles/graph.js:179), and the stale-graph condition that justifies a 404 only exists in develop, so the guard is scoped to match.

Scope

Deliberately narrow. This does not refresh the graph or add a file watcher — hot reloading of the graph (which is also what makes a newly added page 404 until restart) is tracked in #1278 and is a feature. This is just the incorrect status code and unhandled read error on delete, which is wrong regardless of whether the graph ever refreshes.

It also does not change greenwood build or greenwood serve. build still fails loudly on a missing page file, verified by test; serve never reaches this plugin at all, since lifecycles/config.js:36-38 excludes plugin-standard-html from isStandardStaticResource.

Testing

Folded into the existing develop.default case rather than a new directory. A fixtures/deleted.html is copied to src/pages/deleted.html via gallinago's setupFiles before the server starts (so it is in the graph), the test asserts it serves 200, deletes it while the server is still running, and asserts the same route now returns 404. Teardown removes the copy if a failure leaves it behind.

There is no timing element — fs.rmSync completes before the second fetch — so the result is deterministic. Each of the counts below is from 5 consecutive runs of packages/cli/test/cases/develop.default:

result
before this change (test only) 117 passing, 1 failing — 5/5 runs, always AssertionError: expected 500 to equal 404
with the fix 118 passing, 0 failing — 5/5 runs

Baseline before any change was 115 passing; the new describe adds 3 tests.

Wider runs, all green with the fix:

  • all develop.* cases: 313 passing
  • build.default, build.default.pages*, serve.default: 48 passing

prettier --check and eslint are clean on the changed files, as is ls-lint.

Note for the maintainer

The fix for #1770 lands in this same file, packages/cli/src/plugins/resource/plugin-standard-html.js, but at the getMatchingDynamicSsrRoute(...) || {} expression around line 42 — well clear of this hunk around line 56, so the two should merge without conflict.

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.

develop: deleting a page while the dev server is running returns a 500 with a raw ENOENT instead of a 404

1 participant