cloudflare / cloudflare/workers-sdk

[wrangler] preserve_file_names keeps absolute non-JavaScript imports in the Worker bundle

Open
#15,292 3 comments 0 reactions 0 assignees View on GitHub
package:wrangler
Dominant language
TypeScript
Stars
4.5k
Forks
1.5k
Avg merge
3d 8h
Merged PRs (30d)
186

Description

### What versions & operating system are you using?

```text
System:
OS: Linux 6.18.33.2-microsoft-standard-WSL2 x86_64
Binaries:
Node: v24.13.0
pnpm: 9.15.9
Packages:
wrangler: 4.125.0
```

The relevant `preserveFileNames` branch is also unchanged on the current `main` branch as of 2026-08-21.

### Please provide a link to a minimal reproduction

https://gist.github.com/brassring/9c3f96982b386dbcda8de88be4e710d2

### Describe the Bug

When a non-JavaScript module is imported using an absolute path and `preserve_file_names` is enabled, Wrangler copies that absolute build-machine path into the generated Worker bundle and does not write the imported module into the dry-run output directory.

This was originally observed with `@opennextjs/cloudflare`, which intentionally turns external WASM imports into absolute paths before handing the bundle to Wrangler. The reproduction uses a plain text module instead, so it does not depend on OpenNext, Prisma, or WASM.

Steps to reproduce:

1. Clone the reproduction Gist.
2. Run `pnpm install`.
3. Run `pnpm repro`.

Actual result:

- `dist/index.js` contains `import message from "/absolute/build/path/message.txt"`.
- `message.txt` is not copied into `dist`.
- Wrangler exits successfully in dry-run mode even though the bundle contains a machine-local module specifier.
- In the original OpenNext/WASM case, uploading the resulting Worker failed validation with error code `10021`.

When `preserve_file_names` is set to `false`, Wrangler instead emits a hashed relative import and copies the module into `dist`.

Expected result:

Wrangler should produce a deployable module specifier while preserving the filename. If absolute module imports are intentionally unsupported with `preserve_file_names`, Wrangler should fail locally with an actionable error instead of producing a bundle that can only fail during upload.

Could you confirm which behavior is intended? I am happy to follow up with a regression test and fix once the expected path-rebasing behavior is clear.

Relevant source locations:

- Wrangler module collection: https://github.com/cloudflare/workers-sdk/blob/main/packages/wrangler/src/deployment-bundle/module-collection.ts
- OpenNext external module handling: https://github.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/cli/build/patches/plugins/wrangler-external.ts

### Please provide any relevant error logs

```text
Total Upload: 0.23 KiB / gzip: 0.18 KiB
No bindings found.
--dry-run: exiting now.
{ absolutePathPreserved: true, moduleCopied: false }
```

Contributor guide

Open the contributing guide

Research direction

Read packages/wrangler/src/deployment-bundle/module-collection.ts and run the linked Gist's pnpm repro to trace preserve_file_names handling for absolute non-JavaScript imports. Confirm the intended behavior using the dry-run output: the generated bundle should use a deployable module path and include the imported module, or fail locally with an actionable error.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, wasm
Domain
build-system, cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.