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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions