How to Fix: Next 15 | Build fails: Can’t resolve `next/dist/server/route-modules/app-page/vendored/contexts/html-context`
Next 15 build fails with Can't resolve 'next/dist/server/route-modules/app-page/vendored/contexts/html-context': how to fix it
This error usually means your app, a dependency, or your build tooling is importing a private internal Next.js module that changed in Next 15. The missing file is not part of the public API, so once the internal folder layout moved, the production build started failing during module resolution.
Understanding the Root Cause
The path next/dist/server/route-modules/app-page/vendored/contexts/html-context lives under next/dist, which is an implementation detail of Next.js. Packages should not depend on that path directly unless they are tightly coupled to one exact Next.js version.
In Next 15, several internal files were reorganized as part of changes to the App Router, server rendering pipeline, and bundling behavior. If your project or one of its dependencies references that old internal location, the resolver can no longer find it during pnpm build.
This problem often appears in one of these scenarios:
- A third-party package imports from
next/dist/*instead of the public Next.js API. - Your monorepo contains a package compiled against an older Next 13/14 internal structure.
- A custom alias, transpilation rule, or patch rewrites imports incorrectly.
- pnpm exposes dependency boundaries more strictly, so invalid deep imports fail more visibly than with other package managers.
In short, the build is not failing because html-context is missing by accident. It is failing because something depends on a file that should never have been treated as stable.
Step-by-Step Solution
The fix is to find who imports that internal path, then replace, upgrade, patch, or remove that dependency.
1. Find the package importing the missing module
Start by searching your workspace and installed dependencies for the exact path.
grep -R "next/dist/server/route-modules/app-page/vendored/contexts/html-context" .
If you are on Windows or want a faster search tool, use one of these alternatives:
rg "next/dist/server/route-modules/app-page/vendored/contexts/html-context" .
find . -type f | xargs grep -n "next/dist/server/route-modules/app-page/vendored/contexts/html-context"
You are looking for matches in:
node_modules- internal packages in a monorepo
- generated build output accidentally committed or reused
- custom webpack, Babel, or TS transform code
2. Verify your installed Next.js version
Confirm that all workspace packages resolve to the same major version.
pnpm why next
pnpm list next --depth 4
If you see multiple versions of Next.js, especially mixed 14.x and 15.x, that is a major red flag. A package built for one internal layout can break against another.
3. Upgrade the offending dependency
If the search points to a third-party package, check whether a newer version supports Next 15. Update it first instead of patching internals manually.
pnpm up your-problem-package
If this is happening in a monorepo, also update shared UI or app packages that may have compiled artifacts from older Next releases.
4. Remove deep imports from next/dist
If the import exists in your own code, replace it with a public API or refactor the feature so it no longer depends on Next internals.
For example, if code looks like this:
import { HtmlContext } from 'next/dist/server/route-modules/app-page/vendored/contexts/html-context'
That import must be removed. Do not try to rename it to another internal file path. Instead, move the logic to supported APIs such as:
- App Router primitives
next/navigationnext/headersnext/server- documented React context patterns inside your own app
If a package needs request or rendering state, pass that state explicitly rather than reaching into Next’s internal context tree.
5. Clean the install and rebuild
After updates or code changes, remove stale artifacts and reinstall.
rm -rf node_modules .next pnpm-lock.yaml
pnpm install
pnpm build
If you are in a workspace, also clear package-level build outputs:
find . -type d \( -name .next -o -name dist -o -name build \) -prune -exec rm -rf {} +
6. Use a temporary patch only if an upstream fix is not available
If a dependency is unmaintained and still imports the removed internal path, you can patch it locally while waiting for a permanent fix.
pnpm patch package-name
Edit the compiled import inside the temporary patch directory, replacing the invalid deep import with supported code or removing the dependency on that context entirely. Then commit the patch:
pnpm patch-commit /path/to/patched/package
This is a short-term workaround, not the ideal end state.
7. Align all Next-related packages
Make sure related packages are also compatible with Next 15, especially:
reactandreact-domeslint-config-next@next/*tooling- UI libraries with SSR integrations
A typical safe validation step is:
pnpm outdated
pnpm dedupe
Example remediation flow
pnpm why next
rg "next/dist/server/route-modules/app-page/vendored/contexts/html-context" .
pnpm up
rm -rf node_modules .next
pnpm install
pnpm build
If the search result points to one dependency, upgrade or patch that package. If it points to your own source code, remove the deep import completely.
Common Edge Cases
1. The import is coming from generated code, not source
Some monorepos publish or link prebuilt files under dist. Your source may be clean, but the emitted JavaScript still contains the bad import. Rebuild that package from source after updating the code.
2. The project mixes App Router and older assumptions
Libraries written around older server rendering internals may break when used inside a Next 15 App Router application. Even if development mode appears fine, production bundling can fail because the resolver follows a stricter path.
3. pnpm hoisting differences expose the bug
With pnpm, packages do not get the same flattened dependency tree that npm or Yarn sometimes create. That is useful here: it reveals invalid dependency assumptions. A package importing hidden internals may appear to work elsewhere and still fail under pnpm.
4. Turborepo or cache reuse keeps serving stale output
If your repo uses task caching, an older build artifact may still reference the removed Next path. Clear both local caches and any remote cache before validating the fix.
rm -rf .turbo .next node_modules
pnpm install && pnpm build
5. A custom webpack alias is rewriting Next imports
Check next.config.js or shared bundler config for aliases that map next/* paths. An old alias can force the resolver toward a dead internal location.
6. Lockfile drift between local and CI
If CI fails but local builds pass, compare the resolved dependency graph. The issue may be triggered only by a slightly different transitive version.
pnpm install --frozen-lockfile
Then verify the exact package versions in CI logs.
FAQ
Why does this break only on pnpm build and not always during development?
Development and production builds do not resolve modules the same way. Production compilation exercises more of the server bundle, tree-shaking, and route-module code paths. That is often when a bad deep import into next/dist finally surfaces.
Can I fix this by aliasing the missing file to another internal Next.js path?
No. That is fragile and likely to break again on the next release. The correct fix is to stop depending on private Next internals and move to a supported public API or a dependency version that already did that migration.
How do I know whether the problem is in my code or a package?
Search for the exact import string. If it appears under your app or workspace package source, it is your code. If it appears under node_modules or a generated dist folder, it is a dependency or precompiled artifact. That tells you whether to refactor, rebuild, upgrade, or patch.
The practical fix for this issue is simple: identify the deep import, eliminate reliance on next/dist, align all packages on Next 15-compatible versions, then rebuild from a clean install. Once the invalid internal reference is gone, the build error disappears.