fix(patches): return empty object for unhandled manifests in loadManifest#1151
Conversation
🦋 Changeset detectedLatest commit: a695016 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Hey @vicb - just wanted to check in on this. No rush at all, I know you're probably busy. Just wanted to make sure the approach looks reasonable to you, or if you'd prefer I take it in a different direction. Happy to adjust anything. |
|
Can confirm that is working for me in production after copying this patch into the project using |
|
Need this fix too. |
commit: |
|
LGTM, until this is merged you can use |
| // This handles optional manifests (e.g. subresource-integrity-manifest.json when | ||
| // experimental.sri is not configured) and manifests generated in a different build | ||
| // phase (e.g. per-route react-loadable-manifest.json with Turbopack). | ||
| return {}; |
There was a problem hiding this comment.
I don't think this is the right solution, this will just hide other potential errors, if we know the one that could be null, that's the one we should return an empty object, not everything
There was a problem hiding this comment.
Good call - updated to handle only the specific manifests that Next.js loads with handleMissing: true (traced through route-module.ts in vercel/next.js).
The five optional manifests for loadManifest:
react-loadable-manifest.json- Turbopack per-route, not all routes have dynamic importssubresource-integrity-manifest.json- only whenexperimental.sriconfiguredserver-reference-manifest.json- App Router only, Pages Router never generatesdynamic-css-manifest.json- Pages Router + Webpack onlyfallback-build-manifest.json- only for/_errorpage
Everything else still throws. Same approach for evalManifest - only _client-reference-manifest.js gets a safe default ({ __RSC_MANIFEST: {} }) since it's optional for static metadata routes.
| $PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)}); | ||
| ${returnManifests} | ||
| throw new Error(\`Unexpected evalManifest(\${$PATH}) call!\`); | ||
| return {}; |
There was a problem hiding this comment.
Addressed - evalManifest now only handles _client-reference-manifest.js (optional for static metadata routes per route-module.ts line 343). Returns { __RSC_MANIFEST: {} } as the safe default structure. Everything else still throws.
Address review feedback from @conico974 — instead of returning {} for all unknown manifests (which would hide genuine errors), only handle the specific manifests that Next.js loads with handleMissing: true. loadManifest optional manifests (from vercel/next.js route-module.ts): - react-loadable-manifest.json (Turbopack per-route) - subresource-integrity-manifest.json (experimental.sri) - server-reference-manifest.json (App Router only) - dynamic-css-manifest.json (Pages Router + Webpack only) - fallback-build-manifest.json (/_error page only) evalManifest optional manifests: - _client-reference-manifest.js (static metadata routes) Everything else still throws to surface genuine errors.
This did not work for me, trying to run next 16.2 still receives "Unexpected loadManifest(/.next/server/prefetch-hints.json) call!" running with wrangler dev locally |
|
Hey @nathanschram — we've been testing Next.js 16.2.0 (stable, not canary) on Cloudflare Workers and can confirm this PR is needed alongside #1160 for things to work. We found one issue during testing (after manually applying the patch from this PR locally): some manifests are requested without the Root causeNext.js defines some manifest constants without
When My suggestion for this PRFor each manifest in the fallback list, check both with and without $PATH.endsWith("dynamic-css-manifest.json") || $PATH.endsWith("dynamic-css-manifest")Or strip const normalizedPath = $PATH.replace(/\.json$/, "");
if (normalizedPath.endsWith("dynamic-css-manifest")) return {};After manually applying (locally) #1160 + this PR + the extensionless fix above, I can confirm that our Next.js 16.2.0 app renders successfully on Cloudflare Workers (for Platforms, in our case):
Happy to help with the fix or open a follow-up PR if that's easier. Thanks for this PR! |
conico974
left a comment
There was a problem hiding this comment.
LGTM Thanks for the fix
|
@nathanschram Could You fix the prettier issue please ? |
- Fix prettier formatting in changeset - Strip .json extension before matching optional manifests since Next.js defines some constants without it (SUBRESOURCE_INTEGRITY_MANIFEST, DYNAMIC_CSS_MANIFEST, SERVER_REFERENCE_MANIFEST) - Add prefetch-hints to the optional manifest list (new in Next.js 16.2) - All 236 tests pass, tsc clean, prettier clean Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@conico974 Prettier issue should be fixed now - sorry about that. @matthewvolk Great catch on the extensionless manifests - I've updated the matching to strip @bonadio Added Summary of changes in the latest push:
|
Next.js 16.2.0 introduced prefetch-hints.json which crashes on Cloudflare Workers with @opennextjs/cloudflare@1.17.1. The fix (opennextjs/opennextjs-cloudflare#1151) is merged but not yet released to npm.
Next.js 16.2.0 introduced prefetch-hints.json which crashes on Cloudflare Workers with @opennextjs/cloudflare@1.17.1. The fix (opennextjs/opennextjs-cloudflare#1151) is merged but not yet released to npm.
* ppr support * fix experimental in aws * port opennextjs/opennextjs-aws#1107 * add support for segment in PPR * fix composable cache * fix experimental test * make PPR work in cloudflare * bump to 16.2.1 * port pr opennextjs/opennextjs-cloudflare#1151 * fix composable cache cloudflare * fix: update Open-Graph tests to skip and assert cache behavior * format * fix: update revalidate tag test to assert "MISS" for x-nextjs-cache header * enable experimental for cf * fix: rename build:worker script to build:worker:cf for clarity * fix: skip test for cached fetch in ISR due to unresolved issues * basic review * review
Two changes pulled from opennextjs/opennextjs-cloudflare#1151 and #1160: 1. load-manifest.js: when a manifest lookup misses, fall back to {} for the known optional manifests Next.js loads with handleMissing: true (react-loadable, subresource-integrity, server-reference, dynamic-css, fallback-build, prefetch-hints, _client-reference). Unknown manifests still throw to surface real bugs. Without this, dynamic routes 500 when the build-time glob scan misses a conditionally generated manifest. 2. package.json: bump min Next.js to 16.2.3 (CVE-2026-23869). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two changes pulled from opennextjs/opennextjs-cloudflare#1151 and #1160: 1. load-manifest.js: when a manifest lookup misses, fall back to {} for the known optional manifests Next.js loads with handleMissing: true (react-loadable, subresource-integrity, server-reference, dynamic-css, fallback-build, prefetch-hints, _client-reference). Unknown manifests still throw to surface real bugs. Without this, dynamic routes 500 when the build-time glob scan misses a conditionally generated manifest. 2. package.json: bump min Next.js to 16.2.3 (CVE-2026-23869).
## Summary - bump `@opennextjs/cloudflare` from `1.17.1` to `1.19.1` and pin the version in `packages/web/package.json` - pick up the OpenNext Cloudflare fixes for the Next.js 16.2 `prefetch-hints.json` runtime crash I hit during deployment after updating to the latest version of open-inspect - keep Open-Inspect users on a known-good adapter version via the repo lockfile instead of relying on whatever version `npx` might otherwise fetch ## Why I hit a production failure after deploying the Cloudflare web app with Next `16.2.3`: ```text Error 1101 Unexpected loadManifest(/.next/server/prefetch-hints.json) call! ``` Root cause: Next 16.2 introduced `prefetch-hints.json`, but `@opennextjs/cloudflare@1.17.1` did not inline or gracefully handle that manifest in its patched `loadManifest()` runtime shim. Upstream references: - opennextjs/opennextjs-cloudflare#1157 - opennextjs/opennextjs-cloudflare#1160 - opennextjs/opennextjs-cloudflare#1151 `1.19.1` includes the manifest-handling fixes released after `1.17.1`, so this avoids the Cloudflare worker startup crash without keeping our app pinned to an older Next version. ## Validation - verified locally that the failure reproduces with `next@16.2.3` + `@opennextjs/cloudflare@1.17.1` - verified a minimal standalone repro serves successfully after upgrading the adapter to `@opennextjs/cloudflare@1.17.3+` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated development dependency version for improved build tooling compatibility. <!-- end of auto-generated comment: release notes by coderabbit.ai -->

Summary
{}instead of throwing for manifest paths not found during the build-time glob scan inloadManifest()andevalManifest()loadManifest()calls for optional/phase-dependent manifestsProblem
Next.js canary adds
loadManifest()calls for:subresource-integrity-manifest.json- only generated whenexperimental.sriis configured, but loaded unconditionallyreact-loadable-manifest.json- generated by Turbopack, possibly in a different build phaseThe adapter's build-time glob scan doesn't find these files, so the patched function throws at runtime, crashing all dynamic routes with 500.
Fix
Replace the
throw new Error('Unexpected loadManifest...')fallback withreturn {}. This follows the same defensive pattern used by other adapter plugins (instrumentation.ts,find-dir.ts) that return safe defaults for missing files.Test plan
next@canary(16.2.0-canary.53+) using@opennextjs/cloudflareexperimental.sriIS configuredFixes #1141