Skip to content

fix(vtz): invalidate dependents' cache when a file fails to compile [#2766]#2940

Merged
viniciusdacal merged 1 commit into
mainfrom
fix/2766-compile-error-graph-maintenance
Apr 22, 2026
Merged

fix(vtz): invalidate dependents' cache when a file fails to compile [#2766]#2940
viniciusdacal merged 1 commit into
mainfrom
fix/2766-compile-error-graph-maintenance

Conversation

@viniciusdacal
Copy link
Copy Markdown
Contributor

Summary

The dev-server file-watcher loop continued inside the compile-error branch, bypassing process_file_change. If a user introduced a syntax error in utils.ts, transitive dependents kept their stale compiled-cache entries — so even after the error was fixed, dependents could still serve stale compiled code until individually re-touched. Same shape as #2764 (delete events), different trigger.

  • Compile-error branch now falls through to process_file_change so the changed file and its transitive dependents are invalidated.
  • The module-graph update is still skipped on error — don't commit edges scanned from broken source; last-successful edges persist until the next successful compile, which can only over-invalidate (safe).
  • HMR broadcast is suppressed while compile_result.errors is non-empty: the overlay is the user-visible state, and firing Update/FullReload on every broken keystroke would make the client re-fetch a broken module, or (for entry-file edits) reload mid-error and lose in-memory state. The next successful compile drives the refetch.
  • The per-change handler body was moved out of server::http's file-watcher closure into a new server::file_change_handler::handle_file_change so it's reachable from tests without spinning up start_server_with_lifecycle.

Public API Changes

None. @vertz/runtime is documented as internal; the newly-exposed pub fn handle_file_change is used by the in-tree regression test only and is not surfaced anywhere a user would reach.

Test Plan

  • cargo test --all green (incl. new regression test that models page → app → hello and verifies all three cache entries are invalidated when hello.tsx is modified with a syntax error)
  • Regression test has been manually verified to fail when a return; is re-introduced in the compile-error branch
  • cargo clippy --all-targets --release -- -D warnings clean (pre-push hook)
  • cargo fmt --all -- --check clean
  • TS build-typecheck / lint / tests green (pre-push hook)
  • Trojan-source check green

Review

Ran one adversarial review; all three should-fix findings (HMR broadcast on compile error, stale graph-edge comment, single-level dependent test coverage) and the brittle broken-source string nit were addressed. Review notes and resolution: reviews/fix-2766/phase-01-hmr-compile-error.md (not committed to main).

Closes #2766.

🤖 Generated with Claude Code

…2766]

The dev-server file-watcher loop `continue`d inside the compile-error
branch, bypassing `process_file_change`. If a user introduced a syntax
error in `utils.ts`, transitive dependents kept their stale compiled-cache
entries — so even after the error was fixed, dependents could still serve
stale code until individually re-touched. Same shape as #2764 (delete
events), different trigger.

The compile-error branch now falls through to `process_file_change` so
the changed file and its transitive dependents are invalidated. The
module-graph update is still skipped on error (don't commit edges
scanned from broken source); last-successful edges persist until the
next successful compile, which can only cause over-invalidation (safe).

Also suppress the HMR broadcast while `compile_result.errors` is
non-empty: the overlay is the user-visible state, and firing
Update/FullReload on every broken keystroke would make the client
re-fetch a module that will error out, or (for entry-file edits) reload
the page mid-error and lose in-memory state. The cache is invalidated
above; the next successful compile drives the refetch.

As part of the fix, the per-change handler body was moved out of the
file-watcher closure in `server::http` into
`server::file_change_handler::handle_file_change` so it's reachable
from tests without spinning up `start_server_with_lifecycle`.

Closes #2766.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@viniciusdacal viniciusdacal merged commit 7106c64 into main Apr 22, 2026
7 checks passed
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.

Dev server: Modify events with compile errors skip cache/graph maintenance

1 participant