fix(nix): write the registry npmrc where the deps fetch actually reads it #513

Merged
gmackie merged 1 commit from fix/nix-npmrc-userconfig into main 2026-08-28 00:24:49 +00:00
Owner

Corrects #512, which did not work. npm-registry kept failing with ERR_PNPM_FETCH_401 on the merge commit of #512 itself (rev 574dd67101) — which is what gave it away.

Why #512 was inert. It hooked preBuild and wrote the npmrc under $HOME. Reading the nixpkgs source on the node, pnpm.fetchDeps does its work in installPhase, so preBuild never ran at all — and installPhase then does its own export HOME=$(mktemp -d), which would have discarded the file anyway:

installPhase = ''
  runHook preInstall
  ...
  export HOME=$(mktemp -d)

The fix. preInstall runs inside that phase before pnpm does, and NPM_CONFIG_USERCONFIG survives the HOME reset, so the credential actually reaches the fetch. fetchDeps also accepts impureEnvVars as an argument and appends it to its own list, so #512's overrideAttrs — which replaced that list, dropping proxyImpureEnvVars and NIX_NPM_REGISTRY — is gone.

Verified on hetzner-fg, not reasoned about. I got this wrong once tonight by trusting a misread stat, so this time the evidence is direct:

  • patched build fetched the dependencies clean where the unpatched one 401s
  • the resulting store path carries narHash: sha256-4pKTGwBq…, matching the hash recorded here, and was registered during that build — every prior attempt 401'd, so it could not have pre-existed
  • a second run pinned to that hash built forgegraph-registry-0.0.1 through fixupPhase

#512's hash was also wrong — I took it from a store path I had not actually verified. It was never exercised, because the fetch never got past the 401. This one is the hash of a fetch I watched succeed.

Wiring is already in place: FG_NPM_TOKEN is in /etc/forgegraph/agent.env (mode 600) and the agent process has it. The durable version — carrying a registry token in the deployment payload the way CI jobs already do — remains a separate server+agent change.

🤖 Generated with Claude Code

Corrects #512, which did not work. npm-registry kept failing with `ERR_PNPM_FETCH_401` **on the merge commit of #512 itself** (rev `574dd67101`) — which is what gave it away. **Why #512 was inert.** It hooked `preBuild` and wrote the npmrc under `$HOME`. Reading the nixpkgs source on the node, `pnpm.fetchDeps` does its work in **`installPhase`**, so `preBuild` never ran at all — and `installPhase` then does its own `export HOME=$(mktemp -d)`, which would have discarded the file anyway: ```nix installPhase = '' runHook preInstall ... export HOME=$(mktemp -d) ``` **The fix.** `preInstall` runs inside that phase before pnpm does, and **`NPM_CONFIG_USERCONFIG` survives the HOME reset**, so the credential actually reaches the fetch. `fetchDeps` also accepts `impureEnvVars` as an argument and appends it to its own list, so #512's `overrideAttrs` — which *replaced* that list, dropping `proxyImpureEnvVars` and `NIX_NPM_REGISTRY` — is gone. **Verified on hetzner-fg, not reasoned about.** I got this wrong once tonight by trusting a misread `stat`, so this time the evidence is direct: - patched build fetched the dependencies clean where the unpatched one 401s - the resulting store path carries **`narHash: sha256-4pKTGwBq…`**, matching the hash recorded here, and was registered during that build — every prior attempt 401'd, so it could not have pre-existed - a second run pinned to that hash built `forgegraph-registry-0.0.1` through `fixupPhase` **#512's hash was also wrong** — I took it from a store path I had not actually verified. It was never exercised, because the fetch never got past the 401. This one is the hash of a fetch I watched succeed. Wiring is already in place: `FG_NPM_TOKEN` is in `/etc/forgegraph/agent.env` (mode 600) and the agent process has it. The durable version — carrying a registry token in the deployment payload the way CI jobs already do — remains a separate server+agent change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(nix): write the registry npmrc where the deps fetch actually reads it
All checks were successful
CI / gitleaks (pull_request) Successful in 12s
CI / storybook (pull_request) Successful in 2m5s
forgegraph/ci CI passed
CI / ci (pull_request) Successful in 9m30s
1701439c02
#512 hooked preBuild and set HOME. Neither works here: pnpm.fetchDeps does
its work in installPhase, so preBuild never ran, and installPhase then does
its own 'export HOME=$(mktemp -d)', discarding anything written under the
old HOME. The build kept failing with ERR_PNPM_FETCH_401 on the merge commit
of #512 itself, which is what gave it away.

preInstall runs inside installPhase before pnpm does, and NPM_CONFIG_USERCONFIG
survives the HOME reset, so the credential reaches the fetch. fetchDeps also
takes impureEnvVars as an argument and appends it to its own list, so the
overrideAttrs wrapper that replaced that list is gone.

Verified on hetzner-fg rather than reasoned about: patched build fetched the
deps clean where the unpatched one 401s, and the resulting store path carries
narHash sha256-4pKTGwBq..., matching the hash recorded here. A second run at
that hash built forgegraph-registry through fixupPhase.

The previous hash was taken from a store path I had not actually verified —
it was never exercised, because the fetch never got past the 401.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
gmackie/ForgeGraph!513
No description provided.