Found while rehearsing #9497 (the @changesets/cli v3 epic, #9465). It is not caused by that migration — it reproduces identically on today's @changesets/cli@2.31.1, so it is filed on its own.
What is broken
cut-rc.yml's "Build the single version commit" step stages an allowlisted set of paths and then asserts that nothing tracked is left modified-but-unstaged:
LEFT="$(git diff --name-only)"
if [ -n "$LEFT" ]; then
echo "::error::tracked files were modified but fall outside the release file surface, so the version commit would be incomplete. Refusing to push."
pnpm run version now ends with node scripts/sync-docs-image-tags.mjs, which rewrites three paths that the staging pathspec does not cover:
content/docs/deployment/self-hosting.mdx
content/docs/upgrading.mdx
docker/README.md
So LEFT is non-empty and the step exits 1. The cut refuses to push — correctly, by its own rule; the rule's input surface just went stale.
Measured
Throwaway clone of origin/main @ 3397d7ec9 (165 pending changesets), .changeset/pre.json absent, then changeset pre enter rc + the full pnpm run version pipeline, then cut-rc.yml's staging + assertions replayed verbatim:
@changesets/cli@2.31.1 (today's pin)
STAGED count: 156
allowlist regex: accepts every staged path
unstaged assertion: TRIPS on:
content/docs/deployment/self-hosting.mdx
content/docs/upgrading.mdx
docker/README.md
sync-docs-image-tags.mjs's own output for the same run:
docker/README.md
32:6 image-tag: 17.0.0 -> 18.0.0-rc.0
43:3 image-tag: 17.0.0 -> 18.0.0-rc.0
65:45 build-arg: 17.0.0 -> 18.0.0-rc.0
content/docs/deployment/self-hosting.mdx
76:3 image-tag: 17.0.0 -> 18.0.0-rc.0
94:3 image-tag: 17.0.0 -> 18.0.0-rc.0
145:6 image-tag: 17.0.0 -> 18.0.0-rc.0
163:20 npm-pin: 17.0.0 -> 18.0.0-rc.0
content/docs/upgrading.mdx
41:8 image-tag: 17.0.0 -> 18.0.0-rc.0
8 pin(s) across 3 surface(s)
The same replay under @changesets/cli@3.0.0 trips on exactly the same three paths, so the migration neither causes nor cures it.
Why nobody has seen it
sync-docs-image-tags.mjs was added to the version script by #9064 (2026-08-16). v17.0.0 shipped 2026-08-14. No cut has run since the rewriter joined the pipeline, so the assertion has never been reached with these three files dirty. The workflow's allowlist comment still describes a pnpm run version measured on the 17.0.0-rc.5 -> rc.6 train, before the rewriter existed.
release.yml's version-PR lane is unaffected: changesets/action@v1 runs a plain git add ., with no allowlist.
Fix shape
Per #9465 ruling 3 the allowlist follows the measurement. Widen the staging pathspec and the re-check regex in cut-rc.yml to cover the three docs/docker surfaces the version pass legitimately writes — ideally by naming them as the rewriter's declared output rather than by pattern, so the next surface sync-docs-image-tags.mjs learns about fails loudly here again.
Note for whoever takes this: #9498 rewrites this same allowlist for the v3 pre-mode file set. Whichever lands first should carry the other's change or hand it over explicitly — two PRs editing this block is the shape #9465 exists to prevent.
Found while rehearsing #9497 (the @changesets/cli v3 epic, #9465). It is not caused by that migration — it reproduces identically on today's
@changesets/cli@2.31.1, so it is filed on its own.What is broken
cut-rc.yml's "Build the single version commit" step stages an allowlisted set of paths and then asserts that nothing tracked is left modified-but-unstaged:pnpm run versionnow ends withnode scripts/sync-docs-image-tags.mjs, which rewrites three paths that the staging pathspec does not cover:So
LEFTis non-empty and the step exits 1. The cut refuses to push — correctly, by its own rule; the rule's input surface just went stale.Measured
Throwaway clone of
origin/main@3397d7ec9(165 pending changesets),.changeset/pre.jsonabsent, thenchangeset pre enter rc+ the fullpnpm run versionpipeline, then cut-rc.yml's staging + assertions replayed verbatim:sync-docs-image-tags.mjs's own output for the same run:The same replay under
@changesets/cli@3.0.0trips on exactly the same three paths, so the migration neither causes nor cures it.Why nobody has seen it
sync-docs-image-tags.mjswas added to theversionscript by #9064 (2026-08-16). v17.0.0 shipped 2026-08-14. No cut has run since the rewriter joined the pipeline, so the assertion has never been reached with these three files dirty. The workflow's allowlist comment still describes apnpm run versionmeasured on the 17.0.0-rc.5 -> rc.6 train, before the rewriter existed.release.yml's version-PR lane is unaffected:changesets/action@v1runs a plaingit add ., with no allowlist.Fix shape
Per #9465 ruling 3 the allowlist follows the measurement. Widen the staging pathspec and the re-check regex in
cut-rc.ymlto cover the three docs/docker surfaces the version pass legitimately writes — ideally by naming them as the rewriter's declared output rather than by pattern, so the next surfacesync-docs-image-tags.mjslearns about fails loudly here again.Note for whoever takes this: #9498 rewrites this same allowlist for the v3 pre-mode file set. Whichever lands first should carry the other's change or hand it over explicitly — two PRs editing this block is the shape #9465 exists to prevent.