GeezerVison is showing github.com — Fix npm wrapper running the glibc binary on musl (#974) by mikolalysenko · Pull Request #976 · SocketDev/socket-patch
Conversation
LLM Description written by Claude Code:claude-opus-5-5
Fixes #974
Summary
On Alpine/musl, a yarn classic install of @socketsecurity/socket-patch puts both the -gnu and -musl platform packages in node_modules, because yarn 1 ignores libc. The npm wrapper always ran the -gnu binary, which can't start on musl, and then exited 1 with no output. With this fix the wrapper runs the binary that works on the host, and it reports any spawn failure instead of exiting silently.
Root cause
npm/socket-patch/bin/socket-patch picked the first platform package that require.resolved. On Linux that is always -gnu before -musl, and the wrapper never checked libc. It also ignored result.error: when the spawn failed (ENOENT, because the glibc ELF interpreter is missing), it ran process.exit(result.status ?? 1) without printing anything.
Fix
detectLibc(): returns glibc when Node's runtime report has glibcVersionRuntime. Otherwise it returns musl when /lib/ld-musl-* exists, which is the same probe scripts/install.sh uses. The runtime report is checked first so that a glibc host that also has the musl loader installed (Debian musl package) keeps using -gnu.
orderCandidates(): on musl, the -musl package goes first. On glibc or an unknown libc the order stays as before.
runFirstUsable(): when a spawn fails with ENOENT/EACCES/ENOEXEC, the wrapper tries the next installed candidate. If none can run, it prints socket-patch: failed to run <bin>: <error> and exits 1.
- The CLI now runs only when the file is executed directly (
require.main === module). When the file is required it exports the helpers, so the tests can call them. The PLATFORMS table is unchanged.
The Python and gem distributions have no equivalent multi-candidate wrapper in this repo, so nothing parallel needed changing.
Ported main CI fix
162befe cherry-picks #878 (Route Gradle digests through utils::digest). Without it, utils::digest::tests::production_digests_go_through_the_helpers fails coverage/test on every PR against current main. It touches no wrapper code, and it becomes a no-op once #878 merges.
Test evidence
node --test npm/socket-patch/bin/socket-patch.test.mjs
- Before the fix: the new suite fails (
# pass 0, # fail 1). Requiring the wrapper ran the CLI, and the new helpers didn't exist.
- After the fix:
# pass 20, # fail 0.
Regression tests for #974:
- musl is detected when the runtime reports no glibc. glibc wins even when a musl loader is also present. Off Linux the result is null.
- On a musl host the
-musl package comes first for linux x64, arm64, arm and ia32. On glibc, -gnu stays first.
- The wrapper falls back to the next binary when the first can't be spawned.
- A spawn failure prints the binary path and the error. It no longer exits silently.
- End to end: a yarn-classic-style
node_modules holds both packages, and the gnu binary can't start (missing ELF interpreter, so spawn gives ENOENT, the same failure a glibc binary hits on musl). The wrapper exits 0 and runs the musl binary.
Manual checks:
- On the same layout, the
main wrapper exits 1 with no output, and the fixed wrapper prints musl-binary --version and exits 0. When only an unrunnable -gnu is installed, it now prints socket-patch: failed to run …/socket-patch-linux-x64-gnu/socket-patch: spawnSync … ENOENT.
- With the real published
@socketsecurity/socket-patch-linux-x64-{gnu,musl}@4.0.0 installed side by side on a glibc host, the fixed wrapper prints socket-patch 4.0.0 and exits 0. A real Alpine container couldn't be run here (no Docker daemon in the sandbox).
Rust (local):
cargo test -p socket-patch-core --lib production_digests_go_through_the_helpers fails on 26aad6f and passes on 162befe.
- The full
cargo test -p socket-patch-core --lib run gives 5246 passed and 4 failed. All 4 are permission-denial tests that can't trigger when running as root, which this sandbox does (uid 0); CI runs as non-root.
- Local
cargo fmt --check reports diffs only in files this PR doesn't touch, from a local rustfmt version mismatch. CI's fmt check is the authority.
🤖 Generated with Claude Code
Generated by Claude Code
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
Yarn classic ignores the `libc` field, so on Alpine it installs both
the -gnu and the -musl platform package. The npm wrapper always took
the first package that resolved (-gnu), whose glibc binary cannot
start on musl, and then exited 1 without printing anything. Every
socket-patch command failed silently in yarn classic projects on
Alpine and in node:*-alpine CI images.
The wrapper now detects the host libc (Node's runtime report, then
the musl loader probe scripts/install.sh uses) and tries the -musl
package first on musl. If a binary cannot be spawned it tries the
next installed candidate, and if none can run it prints the spawn
error instead of exiting silently.
Fixes #974
Assisted-by: Claude Code:claude-opus-5-5
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
main has failed socket-patch-core's lib tests since Gradle support
(#646) and the digest helpers (#865) both landed. The guard test
production_digests_go_through_the_helpers flags three files #646 added
that still hash inline: crawlers/gradle_cache.rs, patch/jvm_jar.rs and
patch/sidecars/maven.rs. That breaks test, test-release and coverage on
every open PR.
Each inline sha1/sha256 call now goes through sha1_hex_of or
sha256_hex_of, which compute the same lowercase hex. Behaviour is
unchanged.
Assisted-by: Claude Code:claude-opus-5-5
|
[agent] coverage failed on 26aad6f in socket-patch-core --lib. This PR didn't cause it: the diff only touches npm/socket-patch/bin/. The failing test is utils::digest::tests::production_digests_go_through_the_helpers, which has been red on main since #646 and #865 both landed. I reproduced it locally on 26aad6f (FAILED) and ported the existing fix from #878 (Route Gradle digests through utils::digest) as 162befe. The guard test now passes, and the commit becomes a no-op once #878 merges.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 162befe. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Burn-down agent: labeled Ready for review at 162befe (162befeef53037a1fbb8fb7d48c7025b9bcad8ad).
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Ready for review
Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review
Milestone
No milestone
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.
|