nextjs - 💡(How to fix) Fix Turbopack Build Error: NftJsonAsset cannot handle filepath url with custom cache handler using top-level await [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#89769Fetched 2026-04-08 00:21:26
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Timeline (top)
closed ×1commented ×1labeled ×1locked ×1

Production builds (next build) fail with a fatal Turbopack error when using a custom cache handler that contains a top-level await expression. This is a regression introduced in Next.js 16.1.6 — the same configuration worked correctly in Next.js 16.1.1.

Error Message

``` FATAL: An unexpected Turbopack error occurred.

Error: NftJsonAsset: cannot handle filepath url

Debug info:

  • Execution of get_all_written_entrypoints_with_issues_operation failed
  • Execution of EntrypointsOperation::new failed
  • Execution of all_entrypoints_write_to_disk_operation failed
  • Execution of Project::emit_all_output_assets failed
  • Execution of emit_assets failed
  • Execution of emit failed
  • Execution of <NftJsonAsset as Asset>::content failed
  • NftJsonAsset: cannot handle filepath url ```

Root Cause

The error occurs during Turbopack's NFT (Node File Trace) phase when it attempts to analyze a custom cache handler module that uses top-level `await`.

Fix Action

Fix / Workaround

  • Critical for production builds - prevents deployment
  • Blocks security updates - users cannot upgrade to 16.1.6 for security fixes (e.g., GHSA-83fc-fqcc-2hmg)
  • Top-level await is valid ESM - this is a standard ES module feature that should be supported
RAW_BUFFERClick to expand / collapse

Environment

  • Next.js: 16.1.6
  • Turbopack: 23c46498
  • Node.js: 22.x
  • Platform: Docker container (Linux)
  • Build command: next build (with Turbopack)

Description

Production builds (next build) fail with a fatal Turbopack error when using a custom cache handler that contains a top-level await expression. This is a regression introduced in Next.js 16.1.6 — the same configuration worked correctly in Next.js 16.1.1.

Error Message

``` FATAL: An unexpected Turbopack error occurred.

Error: NftJsonAsset: cannot handle filepath url

Debug info:

  • Execution of get_all_written_entrypoints_with_issues_operation failed
  • Execution of EntrypointsOperation::new failed
  • Execution of all_entrypoints_write_to_disk_operation failed
  • Execution of Project::emit_all_output_assets failed
  • Execution of emit_assets failed
  • Execution of emit failed
  • Execution of <NftJsonAsset as Asset>::content failed
  • NftJsonAsset: cannot handle filepath url ```

Root Cause

The error occurs during Turbopack's NFT (Node File Trace) phase when it attempts to analyze a custom cache handler module that uses top-level `await`.

Configuration

next.config.ts: ```typescript import path from "path";

export default { cacheHandlers: { default: path.resolve("./scripts/cache-handler.mjs"), }, }; ```

scripts/cache-handler.mjs: ```javascript async function initializeHandler() { // Async initialization logic (e.g., Redis connection) return { async get(key) { /* ... / }, async set(key, value) { / ... */ }, // ... other cache handler methods }; }

// Top-level await - causes Turbopack to fail in 16.1.6 export default await initializeHandler(); ```

Minimal Reproduction

  1. Create a Next.js 16.1.6 project
  2. Add a custom cache handler with top-level `await`:

```javascript // scripts/cache-handler.mjs async function init() { await new Promise(resolve => setTimeout(resolve, 100)); return { async get(key) { return null; }, async set(key, value) {}, async revalidateTag(tag) {}, }; }

export default await init(); ```

  1. Reference it in `next.config.ts`:

```typescript import path from "path";

export default { cacheHandlers: { default: path.resolve("./scripts/cache-handler.mjs"), }, }; ```

  1. Run `next build`
  2. Expected: Build succeeds (as in 16.1.1)
  3. Actual: Build fails with "NftJsonAsset: cannot handle filepath url"

Regression Timeline

Next.js VersionStatus
16.1.1✅ Works correctly
16.1.6❌ Fatal Turbopack error

Impact

  • Critical for production builds - prevents deployment
  • Blocks security updates - users cannot upgrade to 16.1.6 for security fixes (e.g., GHSA-83fc-fqcc-2hmg)
  • Top-level await is valid ESM - this is a standard ES module feature that should be supported

Expected Behavior

Turbopack's NFT phase should handle ES modules with top-level `await`, as this is a standard ECMAScript feature. The module resolution and tracing should work the same way it did in Next.js 16.1.1.

Additional Context

  • Top-level `await` is commonly used for async initialization in cache handlers, database connections, and configuration loading
  • The error specifically mentions `NftJsonAsset` which appears to be an internal Turbopack class for NFT (Node File Trace) asset generation
  • This affects any custom cache handler that requires async initialization (Redis, database connections, etc.)

Related

  • #71306 - Add Turbopack support for 'use cache' in route handlers
  • #76635 - "use cache"s interaction with custom cache handlers
  • #81811 - Custom cacheHandlers for the new dynamicIO/PPR

extent analysis

Problem Summary

Custom cache handler with top-level await causes fatal Turbopack error in Next.js 16.1.6.

Root Cause Analysis

Top-level await in custom cache handler module causes Turbopack's NFT phase to fail.

Fix Plan

  1. Remove top-level await from custom cache handler module.
  2. Use async initialization inside the cache handler module instead.

Example:

scripts/cache-handler.mjs:

async function initializeHandler() {
  // Async initialization logic (e.g., Redis connection)
  return {
    async get(key) { /* ... */ },
    async set(key, value) { /* ... */ },
    // ... other cache handler methods
  };
}

export default initializeHandler();

next.config.ts:

import path from "path";

export default {
  cacheHandlers: {
    default: path.resolve("./scripts/cache-handler.mjs"),
  },
};

Verification

  1. Run next build with the updated cache handler module.
  2. Verify that the build succeeds without any errors.

Extra Tips

  • Top-level await is a valid ES module feature, but it may not be supported by all bundlers, including Turbopack in Next.js 16.1.6.
  • Consider using async initialization inside the cache handler module instead of top-level await.
  • If you need to use top-level await, consider upgrading to Next.js 16.1.1 or later versions that support it.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING