fix(site): install musl resvg binary so Netlify can bundle the OG function#1759
Merged
Conversation
…ction The site build fails on Netlify during the @astrojs/netlify (v8) adapter's `astro:build:done` hook with: ENOENT: no such file or directory, realpath '.../@resvg+resvg-js@2.6.2/node_modules/@resvg/resvg-js-linux-x64-musl' The adapter bundles the serverless function by tracing the server entry with @vercel/nft, then calling fs.realpath on every traced file. The OG image route (/og/[...path].png) is server-rendered and pulls in the native @resvg/resvg-js binding. nft can't distinguish glibc from musl statically, so it traces both Linux binaries, but pnpm only installs the glibc variant on Netlify — realpath on the missing musl binary throws and the whole build exits non-zero. This is not a regression in any feature commit. The breakage was introduced by the Astro 7 / Vite 8 upgrade (which bumped @astrojs/netlify 7 -> 8); the older v7 adapter bundled resvg fine. It only surfaces on builds that actually run: netlify.toml gates the site build on `turbo query affected --packages site`, so commits that don't touch site/ skip the build entirely and appear "green." Add `supportedArchitectures` so pnpm also installs the musl Linux binaries, giving nft a real file to resolve. Verified that this materializes the resvg-js-linux-x64-musl symlink and leaves pnpm-lock.yaml unchanged (so --frozen-lockfile installs stay valid). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017FVfYwxbfNWwUkzhRdTr3k
✅ Deploy Preview for vjs10-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📦 Bundle Size Report🎨 @videojs/html — no changesPresets (7)
Media (10)
Players (5)
Skins (30)
UI Components (39)
Sizes are marginal over the root entry point. ⚛️ @videojs/react — no changesPresets (7)
Media (9)
Skins (27)
UI Components (33)
Sizes are marginal over the root entry point. 🧩 @videojs/core — no changesEntries (14)
🏷️ @videojs/element — no changesEntries (2)
📦 @videojs/store — no changesEntries (3)
🔧 @videojs/utils — no changesEntries (10)
📦 @videojs/spf — no changesEntries (4)
ℹ️ How to interpretJS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.
Run |
sampotts
approved these changes
Jun 30, 2026
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 free
to 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.
The site build has been failing on
mainsince the Astro 7 / Vite 8 upgrade because we pulled in a stricter version of the Netlify adapter that can't cope with how pnpm installs native addons.This adds one pnpm config block to fix it.
The deets
Note
I edited this, but, there's still some AI jargon in there my brain failed to totally parse. Sorry. Here be vibe-dragons.
When Astro deploys an SSR route to Netlify, the
@astrojs/netlifyadapter has to package that route as a Netlify Function. To do that, it runs@vercel/nft(Node File Trace) over the server entry to discover every file the function will need at runtime, then copies those files into the function bundle.Our OG-image route is server-rendered and uses
@resvg/resvg-jsto rasterize SVG → PNG. resvg is a native Rust addon, so it doesn't ship as one package — it ships as a family of platform-specific binaries declared asoptionalDependencies, and the loader picks the right.nodeat runtime.Two reasonable behaviors collide here:
require-ing several platform binaries. It can prune by OS (the build runs on Linux, so darwin/win32 drop out), but it can't tell glibc from musl statically — so it keeps both Linux variants (gnuandmusl) in the file list.…-linux-x64-gnuand skips…-linux-x64-musl(the package declareslibc: [musl], which pnpm filters out). The musl path never exists on disk.fs.realpathon every traced file — including the musl binary nft listed but pnpm never installed.realpathon a missing path throwsENOENT, theastro:build:donehook crashes unhandled, and the whole build exits non-zero:The fix
Make the missing binary present so nft's
realpathresolves. pnpm has a knob for exactly this —supportedArchitectures— which installs optional deps for architectures beyond the host's:pnpm now installs both Linux variants, the musl symlink exists, the copy step succeeds, and the unused musl
.noderides along in the bundle (~1 MB; the glibc binary still loads at runtime).os: [current]keeps the OS filter intact, so it only adds musl-libc Linux binaries — macOS/Windows dev installs are unaffected.Alternative considered: the adapter's
excludeFilesoption could drop the musl path from the trace instead, avoiding the dead binary. But it's an exact-string match against a hashed.pnpm/…path, so it's brittle across version bumps.supportedArchitecturesis the more durable fix; the cost is ~1 MB of unused binary in the function.https://claude.ai/code/session_017FVfYwxbfNWwUkzhRdTr3k
Note
Low Risk
Workspace-only install policy change for optional native binaries; no application logic or auth/data paths touched.
Overview
Adds
supportedArchitecturestopnpm-workspace.yamlso pnpm installs both glibc and musl Linux optional binaries for native deps like@resvg/resvg-js, not only the host libc.This unblocks Netlify site builds that started failing after the Astro 7 /
@astrojs/netlifyv8 upgrade:@vercel/nfttraces both Linux resvg variants, but the adapter’s copy step callsrealpathon every traced path—when the musl package was never installed, the build crashed with ENOENT. Installing the musl variant gives nft a real path to resolve; runtime still uses the glibc binary on Netlify (~1 MB extra in the function bundle).Reviewed by Cursor Bugbot for commit d67c1e6. Bugbot is set up for automated code reviews on this repo. Configure here.