Skip to content

Apply package.json overrides after frozen install - #6844

Merged
masenf merged 2 commits into
mainfrom
claude/package-override-conflict-4g1xmu
Aug 4, 2026
Merged

Apply package.json overrides after frozen install#6844
masenf merged 2 commits into
mainfrom
claude/package-override-conflict-4g1xmu

Conversation

@masenf

@masenf masenf commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

Fixes the issue where upgrading Reflex to a version that introduces a new package.json override fails with lockfile had changes, but lockfile is frozen.

Root cause: Framework overrides were being merged into package.json while restoring the persisted file from reflex.lock/, which would desync it from the persisted lockfile and cause --frozen-lockfile to 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 new update_package_json_overrides() function before any dependency resolution happens.

Changes

Core logic (reflex/utils/frontend_skeleton.py):

  • Refactored _read_persisted_package_json() into a generic _read_package_json_object() helper
  • Modified _compile_package_json() to preserve persisted overrides verbatim (no framework merging)
  • Added update_package_json_overrides() to merge framework overrides into .web/package.json after the frozen install
  • Updated docstrings to clarify the new override handling strategy

Install flow (reflex/utils/js_runtimes.py):

  • Call update_package_json_overrides() after the frozen install
  • If overrides changed but no packages are being added, run a non-frozen install to resolve the new overrides into the lockfile
  • Updated cache payload to include overrides so changes bust the install cache

Tests (tests/units/test_prerequisites.py):

  • Added _stub_framework_packages() to also stub OVERRIDES for predictable test counts
  • Added 4 new integration tests covering:
    • Applying new overrides after frozen install while preserving user overrides
    • Reconciling lockfile when only overrides change
    • Skipping reconcile when overrides are already applied
    • Cache invalidation when overrides change
  • Added 5 new unit tests for update_package_json_overrides() covering merging, missing sections, no-ops, and malformed files
  • Updated existing tests to reflect that framework overrides are no longer merged during compilation

Test Plan

All new tests pass and cover the override handling logic:

  • test_install_frontend_packages_applies_overrides_after_frozen_install validates the core fix
  • test_install_frontend_packages_reconciles_lockfile_for_overrides_only_change ensures lockfile is refreshed when needed
  • test_install_frontend_packages_skips_reconcile_when_overrides_unchanged prevents unnecessary work
  • test_install_frontend_packages_cache_invalidated_by_new_override ensures cache busting works
  • Unit tests for update_package_json_overrides() cover all edge cases

Existing 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

Review in cubic

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
@masenf
masenf requested a review from a team as a code owner August 4, 2026 17:38
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

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
@codspeed-hq

codspeed-hq Bot commented Aug 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/package-override-conflict-4g1xmu (26acd57) with main (d2c75f4)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR defers framework-owned package overrides until after the restored package.json and lockfile complete their frozen install.

  • Preserves persisted overrides verbatim during package.json compilation.
  • Merges current framework overrides before dependency additions and reconciles override-only changes with a non-frozen install.
  • Includes framework overrides in the frontend-install cache fingerprint.
  • Adds focused coverage for ordering, reconciliation, cache invalidation, merging, and malformed files.

Confidence Score: 5/5

The 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.

Important Files Changed

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review completed against the latest diff

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread reflex/utils/frontend_skeleton.py
Comment thread reflex/utils/js_runtimes.py
@masenf
masenf enabled auto-merge (squash) August 4, 2026 17:55
@masenf
masenf merged commit 7e365ce into main Aug 4, 2026
108 checks passed
@masenf
masenf deleted the claude/package-override-conflict-4g1xmu branch August 4, 2026 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants