Skip to content

fix(start-plugin-core): sort server fn manifest entries for deterministic build output#7287

Merged
schiller-manuel merged 6 commits intoTanStack:mainfrom
DORI2001:fix/sort-server-fn-manifest-entries
Apr 30, 2026
Merged

fix(start-plugin-core): sort server fn manifest entries for deterministic build output#7287
schiller-manuel merged 6 commits intoTanStack:mainfrom
DORI2001:fix/sort-server-fn-manifest-entries

Conversation

@DORI2001
Copy link
Copy Markdown
Contributor

@DORI2001 DORI2001 commented Apr 29, 2026

Fixes #6762.

Problem

getResolverManifestEntries calls Object.entries(serverFnsById) and maps over the result without sorting. The serverFnsById dictionary is built by processing source files in build-system order, which is non-deterministic across machines and runs. Because JS object key iteration follows insertion order, the generated manifest object in the emitted __tanstack-start-server-fn-resolver-*.mjs artifact ends up with keys in a different order on each build — changing the file hash even when no functions have changed.

This breaks:

  • Content-addressed caching (CDN, build caches)
  • Reproducible builds / lockfile verification
  • git diff noise on committed build artifacts

Fix

Sort the entries by ID (stable alphabetic order) before mapping. One-line change in getResolverManifestEntries — no behavioural difference at runtime since getServerFnById looks up by key, not by position.

Summary by CodeRabbit

  • Bug Fixes
    • Resolver manifest entries are now emitted in deterministic lexicographic ID order.
    • Result: more reproducible manifests and consistent module indexing across builds and environments, reducing unexpected diffs and build variability.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3358881c-042e-47a6-92b0-cd37655b2a71

📥 Commits

Reviewing files that changed from the base of the PR and between c2fcdcb and 8a2943e.

📒 Files selected for processing (1)
  • .changeset/silver-lions-sort.md
✅ Files skipped from review due to trivial changes (1)
  • .changeset/silver-lions-sort.md

📝 Walkthrough

Walkthrough

getResolverManifestEntries now sorts Object.entries(serverFnsById) lexicographically by id before mapping to ResolverManifestEntry, ensuring the emitted manifest object has a deterministic key/order across builds.

Changes

Cohort / File(s) Summary
Deterministic Manifest Ordering
packages/start-plugin-core/src/start-compiler/server-fn-resolver-module.ts
getResolverManifestEntries sorts Object.entries(serverFnsById) by id prior to producing ResolverManifestEntry objects, stabilizing the serialized manifest ordering and index-based import assignments.
Changeset
.changeset/silver-lions-sort.md
Adds a patch-level Changeset noting the deterministic sorting change for @tanstack/start-plugin-core.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰✨ I hop and sort each manifest line,

ids lined up neat, no random sign.
Hashes steady, builds hum true,
I munch on chaos, order sprouts anew.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: sorting server function manifest entries to achieve deterministic build output.
Linked Issues check ✅ Passed The pull request successfully implements the core requirement from #6762: sorting manifest entries lexicographically to ensure deterministic build output and stable artifact hashes.
Out of Scope Changes check ✅ Passed All changes are directly related to addressing the deterministic ordering issue in #6762; the modifications to the resolver module and addition of changeset are both within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Bundle Size Benchmarks

  • Commit: 7fa0f39cabf4
  • Measured at: 2026-04-30T06:35:48.614Z
  • Baseline source: history:d6decca41807
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 87.30 KiB 0 B (0.00%) 274.68 KiB 75.83 KiB ██████▁▁▁▁▁
react-router.full 90.80 KiB 0 B (0.00%) 286.19 KiB 79.00 KiB ▁▁▁▁▁▁█████
solid-router.minimal 35.55 KiB 0 B (0.00%) 106.95 KiB 31.97 KiB ▁▁████▁▁▁▁▁
solid-router.full 40.28 KiB 0 B (0.00%) 121.16 KiB 36.16 KiB ▁▁▄███▄▄▄▄▄
vue-router.minimal 53.30 KiB 0 B (0.00%) 152.09 KiB 47.88 KiB ██████▁▁▁▁▁
vue-router.full 58.44 KiB 0 B (0.00%) 168.27 KiB 52.33 KiB ▁▁▁▁▁▁█████
react-start.minimal 101.92 KiB 0 B (0.00%) 322.84 KiB 88.06 KiB ▁▁▁▁▁▁█████
react-start.full 105.34 KiB 0 B (0.00%) 333.17 KiB 90.98 KiB ██████▁▁▁▁▁
react-start.rsbuild.minimal 99.53 KiB -1.92 KiB (-1.90%) 317.16 KiB 85.62 KiB █████████▁▁
react-start.rsbuild.full 102.84 KiB -1.91 KiB (-1.83%) 327.59 KiB 88.41 KiB █████████▁▁
solid-start.minimal 49.55 KiB 0 B (0.00%) 152.77 KiB 43.68 KiB ▁▁████▂▂▂▂▂
solid-start.full 55.33 KiB 0 B (0.00%) 169.68 KiB 48.71 KiB ▁▁▃███▅▅▅▅▅

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/start-plugin-core/src/start-compiler/server-fn-resolver-module.ts`:
- Line 19: The current sort uses localeCompare which is
implementation-dependent; update the comparator used on
Object.entries(serverFnsById) so it compares keys deterministically (e.g.,
replace the localeCompare call with a plain lexical comparator that returns
-1/0/1 using a < b and a > b checks) to ensure consistent ordering for the
output manifest; target the sort call where serverFnsById is turned into entries
and sorted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 09bc559a-5156-4286-b93d-2063875239e2

📥 Commits

Reviewing files that changed from the base of the PR and between d6decca and c855204.

📒 Files selected for processing (1)
  • packages/start-plugin-core/src/start-compiler/server-fn-resolver-module.ts

Comment thread packages/start-plugin-core/src/start-compiler/server-fn-resolver-module.ts Outdated
@DORI2001
Copy link
Copy Markdown
Contributor Author

Good point — switched to a plain lexical comparator (a < b ? -1 : a > b ? 1 : 0) to avoid any locale-sensitivity from localeCompare.

@schiller-manuel
Copy link
Copy Markdown
Contributor

i feel like we had this issue before but i cannot find the PR, didnt we merge something like this already?

@DORI2001
Copy link
Copy Markdown
Contributor Author

Not as far as I can tell — the closest is #7251 which fixed CSS asset ordering (stylesheet load sequence), but getResolverManifestEntries was untouched by that PR. This one sorts the server function entries in the resolver manifest, which comes from a separate serverFnsById dictionary built in source-file-scan order. Happy to dig further if you want to double-check a specific commit.

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented Apr 29, 2026

View your CI Pipeline Execution ↗ for commit b6f8f3b

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 9m 20s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 34s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-29 21:11:56 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 29, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@7287

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@7287

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@7287

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@7287

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@7287

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@7287

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@7287

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@7287

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@7287

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@7287

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@7287

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@7287

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@7287

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@7287

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@7287

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@7287

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@7287

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@7287

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@7287

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@7287

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@7287

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@7287

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@7287

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@7287

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@7287

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@7287

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@7287

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@7287

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@7287

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@7287

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@7287

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@7287

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@7287

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@7287

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@7287

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@7287

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@7287

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@7287

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@7287

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@7287

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@7287

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@7287

commit: c2fcdcb

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 29, 2026

Merging this PR will not alter performance

✅ 5 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing DORI2001:fix/sort-server-fn-manifest-entries (c2fcdcb) with main (7fa0f39)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@schiller-manuel
Copy link
Copy Markdown
Contributor

Add comments to clarify sorting logic for resolver manifest entries.
@schiller-manuel
Copy link
Copy Markdown
Contributor

@DORI2001 please add a changeset

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a flaky task in your failed CI:

Since the failure was identified as flaky, the solution is to rerun CI. Because this branch comes from a fork, it is not possible for us to push directly, but you can rerun by pushing an empty commit:

git commit --allow-empty -m "chore: trigger rerun"
git push

Nx Cloud View detailed reasoning in Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@DORI2001
Copy link
Copy Markdown
Contributor Author

Added a changeset in .changeset/silver-lions-sort.md targeting @tanstack/start-plugin-core as a patch.

@schiller-manuel schiller-manuel merged commit 761fcc0 into TanStack:main Apr 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unstable build output due to unsorted manifest map keys in TanStack build artifact

2 participants