T-CTJF-dedupe-monorepo-h3-skew
Status: closed/done · Impact: medium · Complexity: small
The augmented_books adoption (T-6C0Z, #929) shipped learn_web — now at
solutions/augmented/apps/learn_web after T-C9RD — with a
nitro.prerender.ignore: ["/__nuxt_content"] workaround because prerendering
@nuxt/content’s SQL-dump route crashed on an h3 v1/v2 version skew. An
empirical test isolated the real cause and a robust fix, so the workaround can
be removed instead of carried forward.
| Location | Role today |
|---|---|
solutions/augmented/apps/learn_web/package.json | Pins @nuxt/content 3.10.0, which declares no direct h3 dependency, so its /__nuxt_content route handler’s h3 import floats to whatever the tree resolves |
solutions/augmented/apps/learn_web/nuxt.config.ts | Carries nitro.prerender.ignore: ["/__nuxt_content"] to skip the route that crashes on the h3 skew |
Proposed
Section titled “Proposed”solutions/augmented/apps/learn_web builds and prerenders /__nuxt_content without the
nitro.prerender.ignore workaround, because @nuxt/content is pinned to a
version that declares its own h3 v1 dependency and thus pins its route
handler to h3 v1 independent of the rest of the tree.
Approach
Section titled “Approach”- Bump
@nuxt/content3.10.0→3.15.0insolutions/augmented/apps/learn_web/package.json(3.15 declares"h3": "^1.15.11"directly). - Remove the
nitro.prerender.ignore: ["/__nuxt_content"]block fromsolutions/augmented/apps/learn_web/nuxt.config.ts(keepcontent.experimental.sqliteConnector: "native"— that addresses the unrelatedbetter-sqlite3build issue). - Regenerate
bun.lock; buildlearn_weband confirm/__nuxt_contentprerenders.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
solutions/augmented/apps/learn_web/package.json | modify | @nuxt/content 3.10.0 → 3.15.0 |
solutions/augmented/apps/learn_web/nuxt.config.ts | modify | Remove nitro.prerender.ignore |
bun.lock | modify | Regenerated for the @nuxt/content bump |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
solutions/augmented/apps/learn_web/package.jsonpins@nuxt/content>= 3.15.0. - AC-2:
solutions/augmented/apps/learn_web/nuxt.config.tsno longer setsnitro.prerender.ignorefor/__nuxt_content. - AC-3:
bun run buildinsolutions/augmented/apps/learn_webprerenders/__nuxt_contentand exits 0 (no h3 skew crash).
Out of scope
Section titled “Out of scope”solutions/augmented/apps/augmented_weband other sibling apps that declare@nuxt/test-utilskeep transitive h3 v2 (h3-next) copies in the store; Bun 1.3.14 ignores overrides on npm-aliased deps, so those are not deduped here. Relying on@nuxt/content’s own h3 pin sidesteps them — a full store dedupe is part of the pnpm migration (T-UWRG).
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”- Surfaced by
T-6C0Z’s prerender crash; resolved by an empirical bump/drop test (2026-07-19) — see post-mortem.
Post-mortem
Section titled “Post-mortem”Captured by /sdlc:task-work on 2026-07-19. PR: #961.
Empirical test that set the fix
Section titled “Empirical test that set the fix”Ran a 4-cell matrix in a throwaway worktree (workaround removed in every cell;
sqliteConnector: "native" kept):
| Cell | Change | Result |
|---|---|---|
| 0 — control | nothing else changed | PASS (fresh isolated .bun/ linker scopes the route to h3@1.15.11) |
| 1 | bump @nuxt/content 3.10→3.15 | PASS |
| 2 | drop @nuxt/test-utils | FAIL — the h3 skew crash |
| 3 | bump content and drop test-utils | PASS |
What the test established
Section titled “What the test established”- Dropping
@nuxt/test-utilsis the wrong lever — it causes the crash (Cell 2), not fixes it.@nuxt/content@3.10declares noh3;@nuxt/test-utilshappens to declare a directh3: ^1.15.4that incidentally pinned content’s route handler to h3 v1. Remove it and content drifts toh3@2.0.1-rc→ the crash (Cannot read properties of undefined (reading 'set')atsetResponseHeaderin the h3 v2 build). - Bumping
@nuxt/contentto 3.15.0 is the robust lever — 3.15 declares"h3": "^1.15.11"itself, pinning its route to h3 v1 regardless of what test-utils does (Cell 3 survives even with test-utils gone). Layout-independent. - Cell 0 also passed under a fresh Bun 1.3.14 isolated-linker install, i.e. the workaround may already be dead weight in that layout — but the content-3.15 pin is the fix that holds regardless of linker state, so it’s the one shipped here.
Acceptance criteria coverage
Section titled “Acceptance criteria coverage”- AC-1/AC-2: auto — the two edits.
- AC-3: agent-manual —
learn_webbuild prerenders/__nuxt_contentand exits 0.
Friction and automation gaps
Section titled “Friction and automation gaps”- The original T-CTJF worktree was a stale
planning/draftstub 64 commits behind main with no lease; it was torn down and re-branched fresh. A draft task left with a live worktree is a cleanup gap.