JuliusBrussee/caveman · error

no prebuilt binary for ${os}/${arch} — supported: darwin/arm

Error message

no prebuilt binary for ${os}/${arch} — supported: darwin/arm64, darwin/amd64, linux/arm64, linux/amd64, win32/arm64, win32/amd64

What it means

targetPlatform() in the shared binary installer maps process.arch x64 to amd64 and then requires os in {darwin,linux,win32} and arch in {arm64,amd64}. Any other combination (linux/386, linux/ppc64le, freebsd) has no prebuilt release artifact, so the installer refuses up front instead of downloading a mismatched binary.

Source

Thrown at packages/shared/binary-installer/installer.mjs:69

}

function onPath(name) {
  if (isAbsolute(name) || /[\\/]/.test(name)) return executable(name) ? name : null;
  for (const dir of (process.env.PATH ?? "").split(delimiter)) {
    if (!dir) continue;
    for (const candidate of executableCandidateNames(name)) {
      const path = join(dir, candidate);
      if (executable(path)) return path;
    }
  }
  return null;
}

export function targetPlatform(os = process.platform, nodeArch = process.arch) {
  const arch = nodeArch === "x64" ? "amd64" : nodeArch;
  if (!(os === "darwin" || os === "linux" || os === "win32") ||
      !(arch === "arm64" || arch === "amd64")) {
    throw new Error(`no prebuilt binary for ${os}/${arch} — supported: darwin/arm64, darwin/amd64, linux/arm64, linux/amd64, win32/arm64, win32/amd64`);
  }
  return { os, arch };
}

export function binaryInstallFilename(name, os = process.platform) {
  return os === "win32" ? `${name}.exe` : name;
}

function timeoutMs() {
  const raw = process.env.CAVE_SETUP_TIMEOUT ?? "300";
  const seconds = Number(raw);
  if (!Number.isInteger(seconds) || seconds <= 0) {
    throw new Error(`CAVE_SETUP_TIMEOUT must be a positive integer (got ${JSON.stringify(raw)})`);
  }
  return seconds * 1000;
}

async function asset(url, timeout) {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Run on one of the six supported platform/arch pairs (darwin, linux, or win32 on amd64 or arm64)
  2. Set the binary's env var (CAVEMAN_MCP_BIN / CAVEMAN_SHRINK_BIN / CAVEMAN_BROWSE_BIN) to an executable you built or obtained yourself for your platform — ensureBinary returns it without checking the platform
  3. Build the binary from source in your environment and point the env var at it

Example fix

# before (i386 container)
docker run --platform linux/386 node:20 …  # targetPlatform throws

# after
docker run --platform linux/amd64 node:20 …  # or, for a self-built binary:
export CAVEMAN_MCP_BIN=/usr/local/bin/caveman-mcp-myarch
Defensive patterns

Strategy: validation

Validate before calling

const os = process.platform;
const arch = process.arch === "x64" ? "amd64" : process.arch;
const supported = ["darwin", "linux", "win32"].includes(os) && ["arm64", "amd64"].includes(arch);
if (!supported) process.env.CAVEMAN_MCP_BIN = "/path/to/self-built-binary"; // before any setup call

Type guard

function platformSupported(os, nodeArch) {
  const arch = nodeArch === "x64" ? "amd64" : nodeArch;
  return ["darwin", "linux", "win32"].includes(os) && ["arm64", "amd64"].includes(arch);
}

Try / catch

try { bin = await ensureBinary({ name, envVar }); }
catch (e) {
  if (/no prebuilt binary for/.test(String(e?.message))) { bin = buildFromSource(); }
  else throw e;
}

Prevention

When it happens

Trigger: Running caveman-mcp / caveman-shrink / caveman-browse setup (ensureBinary calls targetPlatform) on 32-bit x86, armv7l, ppc64le, s390x, or a non-darwin/linux/win32 OS.

Common situations: Docker base images like i386/node or node on Alpine armv7; CI runners on niche architectures; Raspberry Pi 32-bit OS; corporately mandated older hardware.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/a60597b1fbb57e0e. Report an issue: GitHub.