Skip to content

[finding] Dependabot splits react and react-dom, so every react patch arrives as a PR that cannot merge on its own #159

Description

@os-zhuang

Found by the repo:objectos execution seat (objectstack#9831) while landing #157 / PR #158. Filed unassigned; recording it, not grading it.

What happened, concretely

react-dom 19.2.6 → 19.2.7 was one of three bumps consolidated into ee74379. Regenerating the lockfile with the natural caret declaration ^19.2.7 did not resolve to 19.2.7 — react-dom@19.2.8 had published upstream in the meantime, so it resolved there and immediately broke:

apps/docs
└─┬ react-dom 19.2.8
  └── ✕ unmet peer react@^19.2.8: found 19.2.7

react-dom@X peer-requires react@^X. react sat at 19.2.7 and was out of scope for that card, so the bump was landed by pinning react-dom exact at 19.2.7.

That unblocked the immediate work. It did not fix the shape underneath it.

The shape

Dependabot files react and react-dom as separate PRs, and they are not separately mergeable. A react-dom PR that arrives alone always carries a peer requirement its sibling PR is holding. Whoever picks it up has three options, and two of them are wrong:

  1. Merge the pair together — correct, but nothing in the PRs says they are a pair, and each one's checks pass in isolation on its own base.
  2. Bump react inside the react-dom PR — widens a scoped change silently.
  3. Pin around it — what chore(deps): consolidate react-dom, tailwindcss, @tailwindcss/postcss bumps #158 did, deliberately and as a bounded call, but it is a workaround, not a fix.

This is not hypothetical or one-off: it is what these two packages do on every patch release, and this repo already accumulated a month-stale react-dom PR partly because of it.

A second-order effect the pin introduced

The two declarations now have different shapes:

"react":     "^19.2.7",   // floats
"react-dom": "19.2.7",    // pinned

Both resolve to 19.2.7 today, so nothing is broken now. But a future non-frozen install can float react upward while react-dom stays put. The peer range ^19.2.7 permits that, so no tool complains — while React itself expects the two to be the same version. That is a mismatch which is silent at install time and only shows up at runtime, which is the worst place for it.

The fix has a precedent already in this repo

.github/dependabot.yml already uses grouping:

    groups:
      objectstack:
        patterns:
          - "@objectstack/*"

A react group covering react, react-dom, @types/react, @types/react-dom would make Dependabot file them as one PR, which is the shape that is actually mergeable. That is a few lines in a file that already does this, not a new mechanism.

Whoever takes it should also decide whether react-dom's exact pin stays or reverts to a caret once the two move together — grouping removes the reason the pin exists, and leaving both would be belt-and-braces rather than a contradiction.

Not claimed

  • I have not checked whether @types/react / @types/react-dom have the same coupling — they are versioned independently of the runtime packages and may not need to be in the group.
  • I have not checked whether grouping interacts with the existing @objectstack/* group in any way that needs care.

Back-links: #157, PR #158, closed-as-superseded #49.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions