Skip to content

Non-deterministic worker bundle: unsorted glob() results in load-manifest codegen #1304

Description

@james-addison-moore

Two glob() calls in the load-manifest patch plugin (dist/cli/build/patches/plugins/load-manifest.js in @opennextjs/cloudflare 1.20.1; its src counterpart) feed codegen directly without sorting. glob's own README documents the filesystem walk as indeterminate order, by design. getEvalManifestRule then orders paths with .toSorted((a, b) => b.length - a.length) — a stable sort — so equal-length paths keep whatever order glob() returned.

Repro: any app with two routes whose *_client-reference-manifest.js paths are equal length (ours: /request and /privacy). The generated if ($PATH.endsWith(...)) chain in handler.mjs swaps branch order between builds of the same commit — we observed ~1 divergent build in 13 from-scratch builds with every input file byte-identical.

Impact: breaks byte-reproducible builds; runtime behavior unaffected (branches are mutually exclusive exact-suffix checks).

Fix: sort both glob() results at the call site — (await glob(...)).sort() in getLoadManifestRule and getEvalManifestRule. We run exactly that as a pnpm patch in production; happy to open a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions