CherryHQ/cherry-studio · critical · Error
Missing prebuilt packages for ${platform}-${arch}: ${missing
Error message
Missing prebuilt packages for ${platform}-${arch}: ${missingPackages.join(', ')}
Run `rm -rf node_modules && pnpm install` — pnpm only reads supportedArchitectures on a fresh install, so plain `pnpm install` (even --force) will not fix it. What it means
Thrown by scripts/before-pack.js during electron-builder packaging when one or more native prebuilt packages required for the target platform/arch are not present in node_modules. Cross-arch prebuilts are pulled in via supportedArchitectures in pnpm-workspace.yaml, but pnpm only honors that setting on a fresh install — once node_modules exists it ignores changes. Shipping without them would crash at runtime on native module load, so the build stops here.
Source
Thrown at scripts/before-pack.js:100
// Most native packages encode Electron's platform key (win32) in their name, but some
// (e.g. sqlite-vec) use the npm `windows` convention. Match either so a win32 build keeps
// sqlite-vec-windows-x64 instead of wrongly excluding it.
const keepPackages = (platform, arch) => {
const platformTokens = platform === 'win32' ? ['win32', 'windows'] : [platform]
return packages.filter((p) => p.includes(arch) && platformTokens.some((t) => p.includes(t)))
}
// Cross-arch prebuilt packages come from supportedArchitectures in pnpm-workspace.yaml —
// pnpm ignores that setting once node_modules exists, so it can't be flipped per pack pass.
// Anything kept for this arch but never installed is a native module the app would fail to
// load at runtime, so stop here instead of shipping it. musl builds are excluded: pnpm
// installs them only on a musl host, and releases are built on glibc.
const assertPrebuiltPackages = (platform, arch) => {
const missingPackages = keepPackages(platform, arch)
.filter((p) => !p.includes('musl'))
.filter((p) => !fs.existsSync(path.join(__dirname, '..', 'node_modules', p)))
if (missingPackages.length > 0) {
throw new Error(
`Missing prebuilt packages for ${platform}-${arch}: ${missingPackages.join(', ')}\n` +
`Run \`rm -rf node_modules && pnpm install\` — pnpm only reads supportedArchitectures ` +
`on a fresh install, so plain \`pnpm install\` (even --force) will not fix it.`
)
}
}
exports.assertPrebuiltPackages = assertPrebuiltPackages
exports.default = async function (context) {
const arch = context.arch === Arch.arm64 ? 'arm64' : 'x64'
const platformName = context.packager.platform.name
const platform = platformToArch[platformName]
assertPrebuiltPackages(platform, arch)
if (platform === 'linux') {
const linuxArch = context.arch === Arch.arm64 ? 'arm64' : context.arch === Arch.x64 ? 'x64' : null
if (!linuxArch) throw new Error(`Unsupported Linux packaging architecture: ${context.arch}`)View on GitHub (pinned to 726446b54c)
Solutions
- Wipe and reinstall so pnpm re-reads supportedArchitectures: rm -rf node_modules && pnpm install. (The error message calls this out — plain pnpm install or pnpm install --force will NOT fix it.)
- Confirm the target platform/arch combinations are listed in supportedArchitectures inside pnpm-workspace.yaml.
- If you added a new native package, add its platform/arch variants to both the packages array in before-pack.js and supportedArchitectures in pnpm-workspace.yaml.
- In CI, do not share/restamp a single node_modules cache across arch matrix entries — key the cache by arch.
Example fix
# before (fails) pnpm install --force # pnpm ignores supportedArchitectures on existing node_modules # after rm -rf node_modules && pnpm install
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build check: ensure every required native package is installed for this arch
const fs = require('fs')
const path = require('path')
const { keepPackages } = require('./scripts/before-pack')
// keepPackages is not exported; replicate the filter or export it for reuse
const missing = require('./scripts/before-pack').assertPrebuiltPackages
// Simpler: run the assert before electron-builder in CI
// node -e "require('./scripts/before-pack').assertPrebuiltPackages('linux','arm64')" Prevention
- Always run rm -rf node_modules && pnpm install when switching arch targets — pnpm ignores supportedArchitectures on existing node_modules.
- Key CI node_modules caches by target arch, not shared across arches.
- When adding a native dependency, add it to both before-pack.js packages list and pnpm-workspace.yaml supportedArchitectures.
When it happens
Trigger: Building for an arch you have not freshly installed for (e.g. node_modules installed on an x64 host, then building a win32-arm64 or linux-arm64 target). Also when supportedArchitectures in pnpm-workspace.yaml was edited but pnpm install was run incrementally instead of cleanly, or when a new native package was added to the packages list but not to supportedArchitectures.
Common situations: CI cached node_modules from a prior arch build; a developer toggling arch targets without wiping node_modules; adding a new native dependency (e.g. a new @img/sharp-* variant) and forgetting to declare it in supportedArchitectures; switching between glibc and musl targets.
Related errors
- Unsupported Linux packaging architecture: ${context.arch}
- Unsupported Linux packaging architecture: ${context.arch}
- [theme-contract] ${declaration.name} is defined twice in ${s
- [theme-contract] ${label} is missing root declarations: ${mi
- [theme-contract] ${label} references missing foundation vari
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/5db845cf27f3361e.
Report an issue: GitHub.