Symptom
All 7 of crates/template-compiler/tests/preprocessor_integration.rs's *_style_url_is_compiled / *_preprocesses_* / *_processes_scss_* tests fail with Cannot find module 'sass' (or less / stylus) — but only on machines whose /tmp/ngc-preprocessor-test-cache-v1/node_modules/sass/ exists from a prior run that was interrupted. The package directory is there; its actual contents are not.
Reproducing on a fresh checkout works (the cache gets installed cleanly on first invocation). Reproducing on a machine with a corrupted cache fails every time until the cache is removed by hand.
Root cause
preprocessor_cache() decides the cache is good if each expected package directory exists:
let all_present = [\"sass\", \"less\", \"stylus\"]
.iter()
.all(|pkg| node_modules.join(pkg).is_dir());
if all_present {
return Some(node_modules);
}
An interrupted npm install (Ctrl-C, OS shutdown, network blip, etc.) can leave behind a node_modules/sass/ that only contains an early-installed sub-tree like types/ while the package's real entry point (package.json, dist/, lib/) never got written. The directory check passes, the cache is returned, the symlinked subprocess fails with Cannot find module 'sass'.
Suggested fix
Tighten the cache validity check to require the package's manifest, not just its folder. Something like:
let all_present = [\"sass\", \"less\", \"stylus\"]
.iter()
.all(|pkg| node_modules.join(pkg).join(\"package.json\").is_file());
A corrupted cache then falls through to the re-install path instead of poisoning every preprocessor test on the box.
Why this matters
Whoever hits this for the first time will see all eight preprocessor tests fail with a confusing "missing module" diagnostic from a Node subprocess and have no obvious lead — the test logs don't say "installing sass..." (because the cache looks present), and the failures look like they're inherent to the runtime rather than a stale /tmp artifact. Tightening the check makes the cache self-healing.
Repro on a clean cache
rm -rf /tmp/ngc-preprocessor-test-cache-v1
cargo test -p ngc-template-compiler --test preprocessor_integration
# → 8 passed
To synthesise the broken state (then watch all but the diagnostics test fail):
mkdir -p /tmp/ngc-preprocessor-test-cache-v1/node_modules/sass/types
mkdir -p /tmp/ngc-preprocessor-test-cache-v1/node_modules/less
mkdir -p /tmp/ngc-preprocessor-test-cache-v1/node_modules/stylus
cargo test -p ngc-template-compiler --test preprocessor_integration
Notes
- Not a runtime / compiler bug; purely a test-harness robustness issue.
- CI on
ubuntu-latest runs in a clean container each time and has never hit this.
- No PR open for it yet — the surface is one cache-validity predicate.
Symptom
All 7 of
crates/template-compiler/tests/preprocessor_integration.rs's*_style_url_is_compiled/*_preprocesses_*/*_processes_scss_*tests fail withCannot find module 'sass'(orless/stylus) — but only on machines whose/tmp/ngc-preprocessor-test-cache-v1/node_modules/sass/exists from a prior run that was interrupted. The package directory is there; its actual contents are not.Reproducing on a fresh checkout works (the cache gets installed cleanly on first invocation). Reproducing on a machine with a corrupted cache fails every time until the cache is removed by hand.
Root cause
preprocessor_cache()decides the cache is good if each expected package directory exists:An interrupted
npm install(Ctrl-C, OS shutdown, network blip, etc.) can leave behind anode_modules/sass/that only contains an early-installed sub-tree liketypes/while the package's real entry point (package.json,dist/,lib/) never got written. The directory check passes, the cache is returned, the symlinked subprocess fails withCannot find module 'sass'.Suggested fix
Tighten the cache validity check to require the package's manifest, not just its folder. Something like:
A corrupted cache then falls through to the re-install path instead of poisoning every preprocessor test on the box.
Why this matters
Whoever hits this for the first time will see all eight preprocessor tests fail with a confusing "missing module" diagnostic from a Node subprocess and have no obvious lead — the test logs don't say "installing sass..." (because the cache looks present), and the failures look like they're inherent to the runtime rather than a stale
/tmpartifact. Tightening the check makes the cache self-healing.Repro on a clean cache
To synthesise the broken state (then watch all but the diagnostics test fail):
Notes
ubuntu-latestruns in a clean container each time and has never hit this.