Apply package.json overrides after frozen install - #6844
Conversation
A Reflex upgrade that introduces a new entry in `constants.PackageJson.OVERRIDES` broke `reflex run` for any app with a persisted `reflex.lock/`. Restoring `reflex.lock/package.json` merged the framework overrides in on the way to `.web`, so the restored package.json no longer matched the `bun.lock` it was persisted alongside, and the initial `bun install --frozen-lockfile` aborted with `error: lockfile had changes, but lockfile is frozen`. Upgrading 0.9.7 (override `cookie`, direct dep `postcss@8.5.14`) to 0.9.8a2 (override `postcss@8.5.23`) reproduces it: the new override forces a different resolution for a package the lockfile already pinned. `overrides` participate in dependency resolution, so they now stay exactly as persisted while the package.json/lockfile pair is restored, and the framework-owned entries are merged into `.web/package.json` right after the frozen install instead. The dependency adds that follow resolve against them and refresh the lockfile; when there is nothing to add, a non-frozen install reconciles it so the persisted pair is ready for the next frozen install. `scripts` are unaffected and keep being repaired during the restore, since they play no part in resolution. Also add `OVERRIDES` to the frontend-install cache fingerprint, so an upgrade that changes only the overrides invalidates the cache and actually applies them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018WXodmwe6tFZ6DkweqArij
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
The fragment was named after #6792, the PR that introduced the regression, which would render a changelog link to the wrong PR. Reword the text to describe the user-visible symptom rather than the implementation change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018WXodmwe6tFZ6DkweqArij
Merging this PR will not alter performance
Comparing Footnotes
|
Greptile SummaryThis PR defers framework-owned package overrides until after the restored package.json and lockfile complete their frozen install.
Confidence Score: 5/5The PR appears safe to merge, with the changed install flow preserving the frozen package pair and reconciling newly applied overrides before persistence. Override changes always reach a dependency resolver through either an add command or the new non-frozen install, after which the updated package.json and lockfiles are synchronized together.
|
| Filename | Overview |
|---|---|
| reflex/utils/frontend_skeleton.py | Refactors package.json reading and adds a post-frozen-install override merge while preserving persisted lockfile inputs. |
| reflex/utils/js_runtimes.py | Applies overrides after the initial frozen install, resolves override-only changes, and includes overrides in cache invalidation. |
| tests/units/test_prerequisites.py | Adds comprehensive tests for override ordering, persistence, reconciliation, cache behavior, and merge edge cases. |
| news/6844.bugfix.md | Accurately documents the frozen-lockfile upgrade fix. |
Reviews (1): Last reviewed commit: "Point news fragment at #6844 and reword ..." | Re-trigger Greptile
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Type of change
Description
Fixes the issue where upgrading Reflex to a version that introduces a new
package.jsonoverride fails withlockfile had changes, but lockfile is frozen.Root cause: Framework overrides were being merged into
package.jsonwhile restoring the persisted file fromreflex.lock/, which would desync it from the persisted lockfile and cause--frozen-lockfileto fail.Solution: Defer merging framework overrides until after the frozen install completes. This keeps the restored
package.json/lockfile pair intact for the frozen install, then applies overrides via a newupdate_package_json_overrides()function before any dependency resolution happens.Changes
Core logic (
reflex/utils/frontend_skeleton.py):_read_persisted_package_json()into a generic_read_package_json_object()helper_compile_package_json()to preserve persisted overrides verbatim (no framework merging)update_package_json_overrides()to merge framework overrides into.web/package.jsonafter the frozen installInstall flow (
reflex/utils/js_runtimes.py):update_package_json_overrides()after the frozen installTests (
tests/units/test_prerequisites.py):_stub_framework_packages()to also stubOVERRIDESfor predictable test countsupdate_package_json_overrides()covering merging, missing sections, no-ops, and malformed filesTest Plan
All new tests pass and cover the override handling logic:
test_install_frontend_packages_applies_overrides_after_frozen_installvalidates the core fixtest_install_frontend_packages_reconciles_lockfile_for_overrides_only_changeensures lockfile is refreshed when neededtest_install_frontend_packages_skips_reconcile_when_overrides_unchangedprevents unnecessary worktest_install_frontend_packages_cache_invalidated_by_new_overrideensures cache busting worksupdate_package_json_overrides()cover all edge casesExisting tests updated to match new behavior where framework overrides are applied post-frozen-install rather than during compilation.
closes #6792
https://claude.ai/code/session_018WXodmwe6tFZ6DkweqArij