Uh oh!
There was an error while loading. Please reload this page.
ci(release): drop the inherited npm_config_globalconfig, so the nested pnpm can't hand npm a self-colliding config - #10148
Merged
Merged
Conversation
…d pnpm can't hand npm a self-colliding config
17.5.0 failed to publish after a fully green build (run 32355381481) with an
error carrying no npm error code at all:
Received an unexpected error for @objectstack/account: (no code)
Exit prior to config file resolving
cause
double-loading config "/home/runner/.config/pnpm/rc" as "global", previously loaded as "user"
npm refuses to start when its "user" and "global" config resolve to the SAME
file — it aborts inside @npmcli/config before it parses argv, which is why
changesets could only report "(no code)". Three layers stack up to produce that
one file twice:
1. `pnpm run release` exports npm_config_globalconfig=~/.config/pnpm/rc to
every child; pnpm forces `{globalconfig: join(configDir, 'rc')}` into its
rawConfig unconditionally.
2. `changeset publish` v3 detects the pnpm workspace and shells out to
`pnpm info` / `pnpm publish` per package, where v2 always shelled out to
`npm`. The publish therefore runs a NESTED pnpm underneath `pnpm run`.
3. That nested pnpm reads the inherited value back in and, delegating `info`
to npm, hands the npm child BOTH npm_config_userconfig AND
npm_config_globalconfig pointing at that file (pnpm/pnpm#10914, unfixed on
the 10.31.0 line we pin).
Only layer 2 is new, which is why 2026-08-14's release was green on the same
pnpm pin: @changesets/cli@^2.31.1 spawned npm directly, so npm saw
userconfig=$HOME/.npmrc against globalconfig=~/.config/pnpm/rc — two files, no
collision. The bump to ^3.0.0 routed the publish through a nested pnpm.
Dropping the inherited value is the whole fix. pnpm recomputes its own global
config path from configDir either way, so nothing pnpm needs is lost, and npm
falls back to its own default global config while keeping $HOME/.npmrc — where
release.yml writes NPM_TOKEN — as the user config. `pnpm publish`'s npm child
was already passed only globalconfig and never userconfig, so auth resolution is
unchanged.
Verified in the release lane's exact shape on the pinned pnpm 10.31.0
(`pnpm run` -> bash script -> nested pnpm): the negative control reproduces the
CI error verbatim, and with the unset the nested call returns registry JSON.
Forcing npm_config_userconfig=$HOME/.npmrc instead was tested and does NOT work
— the nested pnpm recomputes it and overrides whatever we export.
Fixes#10146
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SRPcZzc7rfBQsNxJw3BSRh… 17.1.0, not 17.5.0 17.5.0 in that run's log is `@object-ui/console@17.5.0`, the vendored objectui build, not this repo's version. packages/cli/package.json at the run's SHA (47d1ae8, main's tip) declares 17.1.0, and the publish job's guard only proceeds when the dispatched input equals that string — so 17.1.0 is what failed, and 17.1.0 is what the re-dispatch publishes. npm still has latest 17.0.0 and 404s on 17.1.0, confirming the failed run wrote nothing. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRPcZzc7rfBQsNxJw3BSRh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#10146
What broke
17.1.0 failed to publish after a fully green build (run 32355381481), with an error carrying no npm error code at all:
npm refuses to start when its "user" and "global" config resolve to the same file — it aborts inside
@npmcli/configbefore it parses argv, which is why changesets could only report(no code).@objectstack/accountis just the first package to report; every package fails identically. Nothing was published — the run died before the first registry write, and@objectstack/cli@17.1.0is still 404 on the registry.Why that file arrives twice
pnpm run releaseexportsnpm_config_globalconfig=~/.config/pnpm/rcto every child; pnpm forces{globalconfig: join(configDir, 'rc')}into itsrawConfigunconditionally.changeset publishv3 detects the pnpm workspace and shells out topnpm info/pnpm publishper package, where v2 always shelled out tonpm. The publish therefore runs a nested pnpm underneathpnpm run.infoto npm, hands the npm child bothnpm_config_userconfigandnpm_config_globalconfigpointing at that one file (pnpm/pnpm#10914, unfixed on the 10.31.0 line we pin).Only layer 2 is new — which is why 2026-08-14's release was green on the same pnpm pin. It ran
@changesets/cli@^2.31.1, whose npm-only spawn sawuserconfig=$HOME/.npmrcagainstglobalconfig=~/.config/pnpm/rc: two files, no collision. The bump to^3.0.0routed the publish through a nested pnpm.The change
One line in
scripts/release-publish.sh, ahead ofchangeset publish:unset npm_config_globalconfig NPM_CONFIG_GLOBALCONFIGplus the comment block explaining why it cannot be simplified away. pnpm recomputes its own global config path from
configDireither way, so nothing pnpm needs is lost, and npm falls back to its own default global config while keeping$HOME/.npmrc— whererelease.ymlwritesNPM_TOKEN— as the user config.pnpm publish's npm child was already passed onlyglobalconfigand neveruserconfig, so auth resolution is unchanged.Verification
Reproduced and fixed in the release lane's exact shape on the pinned pnpm 10.31.0 (
pnpm run→ bash script → nested pnpm):unset: the nested call returns registry JSON, exit 0.unset,pnpm publish's npm child is handed neitheruserconfignorglobalconfig, so npm resolves$HOME/.npmrcas its user config — the file the workflow writes the token into.Two alternatives were tested and rejected: forcing
npm_config_userconfig=$HOME/.npmrcdoes not work (the nested pnpm recomputes and overrides it), and pinning a newer pnpm is a repo-wide package-manager move for a bug with no known fixed version on this line.Notes
skip-changesetapplied per the gate's route 2 (nothing here releases).scripts/**is not in theGOVERNED_SURFACESregister).version-prandrelease-integrity; thepublishjob isworkflow_dispatch-only behindenvironment: release. Re-dispatchingrelease.ymlfor 17.1.0 is the maintainer's act (Prime Directive Add missing Field.phone() helper and factory methods for Action/Dashboard/Report #15).