## Summary
[PR #9404](#9404) (`feat(backend): add
global libc preference`) taught Node's slug builder to append `-musl`
for musl targets but kept routing through `nodejs.org/dist/`, which does
not host musl tarballs (they live at `unofficial-builds.nodejs.org`).
The visible symptom was in [PR
#9396](#9396 `mise.lock` diff: the
URL gained a `-musl` suffix while the checksum stayed pinned to the
original glibc tarball.
```toml
[tools.node."platforms.linux-x64-musl"]
checksum = "sha256:dbf5b8665..." # ← still the glibc checksum
url = ".../v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" # ← 404, wrong host
```
Mechanically: `resolve_lock_info` builds a 404'ing URL on
`nodejs.org/dist`, fetches the wrong `SHASUMS256.txt` (which doesn't
list `-musl.tar.gz`), gets `None` back, and the lockfile merge preserves
the **stale glibc checksum** alongside the new URL. Anyone running `mise
install` against that lockfile on a musl system would either 404 or hit
a checksum mismatch.
The aqua/github-backed tools in the same release diff updated cleanly
because their checksum source rotates with the artifact. Node is unique
in fetching checksums from a separate `SHASUMS256.txt`.
## Changes
### `src/plugins/core/node.rs`
Add `mirror_url_for(&SettingsNode, filename)` that swaps to
`https://unofficial-builds.nodejs.org/download/release/` when a filename
references a musl artifact and the user has not set a custom
`node.mirror_url`. Wire it into `resolve_lock_info`, `get_tarball_url`,
`BuildOpts::new`, and `shasums_url` so the tarball URL and the matching
`SHASUMS256.txt` always come from the same host. Three unit tests cover
routing (default → glibc, musl → unofficial-builds, custom mirror passes
through unchanged).
### `src/lockfile.rs`
Defense in depth: when merging `PlatformInfo` (both in
`set_platform_info` and `merge_with`), drop the other side's
`checksum`/`size`/`url_api` if URLs disagree — those fields describe a
specific artifact and become stale once the URL changes. The
pre-existing `test_platform_info_merge_prefers_sha256` was asserting
that sha256 should win even across mismatched URLs, which is exactly the
latent bug; updated it to use a shared URL and added
`test_platform_info_merge_drops_stale_checksum_on_url_change`.
### `mise.lock`
Re-ran `mise lock node` to fix the three corrupted node musl entries.
Checksums verified against upstream:
```sh
$ curl -fsSL https://unofficial-builds.nodejs.org/download/release/v24.14.0/SHASUMS256.txt | grep -E "linux-(arm64|x64)-musl\.tar\.gz"
8f81d47b7f... node-v24.14.0-linux-arm64-musl.tar.gz
bae0f23204... node-v24.14.0-linux-x64-musl.tar.gz
```
Both match what mise now writes.
## Test plan
- [x] `cargo test` — 778 passed, 0 failed (includes 3 new node tests + 1
new lockfile test, plus an updated test that previously asserted the
latent bug).
- [x] `cargo clippy --all-features --tests` — clean.
- [x] `cargo fmt` — clean.
- [x] `mise lock node` against this branch produces correct URLs +
checksums for all three node musl platform variants.
- [ ] Install on Alpine / musl host: `MISE_LIBC=musl mise install
node@24.14.0` should download from `unofficial-builds.nodejs.org` and
run.
- [ ] Glibc regression: same flow without `MISE_LIBC=musl` should still
hit `nodejs.org/dist`.
*This PR was generated by an AI coding assistant.*
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes Node.js download/checksum URL selection and lockfile merge
behavior, which can affect installs and lockfile correctness across
platforms; scope is contained with added tests.
>
> **Overview**
> Fixes Node.js *musl* installs/lock resolution by routing musl tarball
URLs (and their matching `SHASUMS256.txt`/signature URLs) to
`unofficial-builds.nodejs.org` when using the default mirror, while
still respecting user-configured `node.mirror_url`.
>
> Hardens lockfile merging so when a platform artifact `url` changes,
stale artifact-bound fields (`checksum`, `size`, `url_api`) from the
other side are dropped instead of preserved, preventing mismatched
URL+checksum pairs.
>
> Regenerates `mise.lock` Node musl entries to use the unofficial-builds
URLs with updated sha256 checksums, and adds/updates unit tests covering
the new mirror routing and merge semantics.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
dd68707. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🚀 Features
🐛 Bug Fixes
📦️ Dependency Updates
📦 Registry
Chore
New Contributors