Theme compile failures are structured hard errors, not silent DEFAULT_CSS (bd-jsvetdea) - #661
Conversation
Plan skeleton + repro fixture. The Err arm in variant_css ships DEFAULT_CSS on any grass failure; the Warn trace event goes to a NoopObserver, so nothing reaches the CLI at any verbosity. grass points at a Quarto-internal line of the assembled bundle, not the user's file. Hub-client vitest leg of pre-flight verify is red under Node 26 (localStorage undefined) — filed as bd-lh30hlvd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xwth8pr6ewSbExXRBNpQWY
…_CSS (bd-jsvetdea, bd-qmpygp02) A grass failure while compiling the theme bundle used to be caught in variant_css, logged as a Warn trace event (which no CLI observer receives), and replaced by the static 7 KB DEFAULT_CSS; the render reported success. A one-line unit mistake in a user theme ($grid-body-width: 52rem) silently shipped an unstyled page. Every compile failure is now a PipelineError::Structured through theme_diagnostic: - Q-14-6 "Theme SCSS compilation failed": the grass / dart-sass text verbatim, anchored at the whole `theme:` value (the compiler only knows lines of the assembled bundle), with a hint saying so. Applies to the themed path, the no-user-input default bundle, and the reveal path (which fell back to the vendored stock theme). - Q-14-7 "Theme file has no layer boundary markers": InvalidScssFile, anchored at the offending `theme:` entry when its resolved path matches one, else at the whole value. The three wrappers keep SassError instead of stringifying it; InvalidScssFile gains a location field; theme_diagnostic gains sass_error_to_parse_error_at(err, fallback_location, candidates). Because the anchor is a _quarto.yml span, the render summary's source-location coalescing prints one report per project with an "Affected files" tail. Resolves bd-36vmz7nk (decision: fatal). Catalog entries, docs pages, and sidebar entries added; unit, diagnostic, and CLI e2e tests written first and verified failing on the old behavior. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xwth8pr6ewSbExXRBNpQWY
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
… (bd-jsvetdea) Four *.wasm.test.ts files load the WASM module by hand and render without calling setVfsCallbacks, so dart-sass cannot resolve the Bootstrap bundle's `@import "vendor/rfs"`. The theme stage used to mask that by silently shipping DEFAULT_CSS, and the tests only inspected HTML, so they passed against an unstyled page. Now that a default-bundle compile failure is a Q-14-6 hard error, 20 tests failed in CI. Add src/test-utils/wasmSassVfs.ts (wireSassVfs) mirroring the production wiring in preview-runtime's wasmRenderer.ts, and call it from each file's beforeAll. npm run test:wasm: 133/133. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xwth8pr6ewSbExXRBNpQWY
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xwth8pr6ewSbExXRBNpQWY
|
CI finding on the first run: 20 hub-client WASM tests failed with Fixed in c0a6230: a shared |
Resolves the expected overlap with the theme-compile-error work: theme_diagnostic keeps both the Q-14-7 (InvalidScssFile) and Q-14-8 (InvalidBrandFontWeight) arms and the Q-14-6 catch-all replaces this branch's old code-less fallback; SassError::with_location and sass_error_location cover both new variants; the errors sidebar lists Q-14-6, Q-14-7, Q-14-8 in code order. The brand-file bind candidate and main's fallback_location coexist in sass_error_to_parse_error_at. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NE1UEmUUagZwZ5APMZYfra
…bering Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CoQm2W4rtvPQNDtkYKdb6D
Summary
A grass failure while compiling the theme bundle used to be caught in
variant_css, logged as aWarntrace event (which no CLI observer receives), and replaced by the static 7 KBDEFAULT_CSS. The render reported success. A one-line unit mistake in a user theme ($grid-body-width: 52rem) silently shipped an unstyled page.Every theme compile failure is now a
PipelineError::Structuredthroughtheme_diagnostic:theme:value (the compiler only knows lines of the assembled bundle), with a hint saying so. Applies to the themed path, the no-user-input default bundle, and the reveal path (which used to fall back to the vendored stock theme).InvalidScssFile, anchored at the offendingtheme:entry when its resolved path matches one, else at the whole value.Plumbing: the three compile wrappers keep
SassErrorinstead of stringifying it;InvalidScssFilegains alocationfield;theme_diagnosticgainssass_error_to_parse_error_at(err, fallback_location, candidates). Because the anchor is a_quarto.ymlspan, the render summary's source-location coalescing prints one report per project with an "Affected files" tail.Closes bd-jsvetdea and bd-qmpygp02; resolves bd-36vmz7nk (decision: fatal). Follow-ups filed: bd-c1gf9xmk (layer provenance so Q-14-6 can name
theme.scss:2), bd-e1psgogt (audit remainingWarntrace sites;-vfilter never matchesquarto_core).Plan:
claude-notes/plans/2026-09-08-theme-scss-compile-error-swallowed.md.Verification
Ok(DEFAULT_CSS)/ no code).cargo nextest run --workspace: 13753 passed. Clippy andcargo xtask lintclean. hub-clientnpm run build:all(WASM leg) succeeds.claude-notes/plans/theme-scss-compile-error-swallowed-investigation/repro/):A two-page site prints the block once, followed by
Affected files: …/about.qmd, …/index.qmd.docs/renders 271/271 pages with no Q-14-6 (nothing previously masked turns red).Note: the hub-client vitest leg of
cargo xtask verifyis red locally under Node 26 (localStorageundefined), unrelated to this change — filed as bd-lh30hlvd.🤖 Generated with Claude Code
https://claude.ai/code/session_01Xwth8pr6ewSbExXRBNpQWY