How to Fix: Next 15 | Build fails: Can’t resolve `next/dist/server/route-modules/app-page/vendored/contexts/html-context`

6 min read

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/navigation
  • next/headers
  • next/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.

Make sure related packages are also compatible with Next 15, especially:

  • react and react-dom
  • eslint-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.

Leave a Reply

Your email address will not be published. Required fields are marked *