paperclipai/paperclip · error · Error

Pinned OpenCode source executable is not a regular file

Error message

Pinned OpenCode source executable is not a regular file

What it means

Before hard-linking, the script verifies the baseline OpenCode executable at <baselineRoot>/bin/opencode is a regular file. If lstat reports anything else (directory, symlink, etc.), materialization aborts because the hard-link source is not a usable executable.

Source

Thrown at packages/paperclip-runner/scripts/materialize-opencode-binary.mjs:60

  if (platform !== "linux" || architecture !== "x64") {
    throw new Error(
      `Pinned OpenCode materialization requires linux/x64, received ${platform}/${architecture}`,
    );
  }

  const packageRoot = realpathSync(
    options.packageRoot ??
      resolve(import.meta.dirname, "../node_modules/opencode-ai"),
  );
  const dependencyRoot = dirname(packageRoot);
  const baselineRoot = realpathSync(join(dependencyRoot, BASELINE_PACKAGE));
  assertPackage(packageRoot, "opencode-ai");
  assertPackage(baselineRoot, BASELINE_PACKAGE);

  const source = join(baselineRoot, "bin", "opencode");
  const target = join(packageRoot, "bin", "opencode.exe");
  if (!lstatSync(source).isFile()) {
    throw new Error("Pinned OpenCode source executable is not a regular file");
  }
  if (existsSync(target)) {
    if (!lstatSync(target).isFile()) {
      throw new Error("OpenCode target executable is not a regular file");
    }
    unlinkSync(target);
  }
  try {
    linkSync(source, target);
  } catch (error) {
    const code = error?.code;
    if (!new Set(["EACCES", "EMLINK", "EPERM", "EXDEV"]).has(code)) {
      throw error;
    }
    copyFileSync(source, target);
  }
  chmodSync(target, 0o755);

View on GitHub (pinned to 01ad858492)

Solutions

  1. Inspect 'ls -la <baselineRoot>/bin/opencode' — reinstall the baseline package so bin/opencode is a real regular file.
  2. If the installer created a symlink shim, point baselineRoot at the package containing the real binary.
  3. Reinstall the pinned baseline package (rm -rf node_modules/<baseline> && pnpm install) to restore a proper binary.
  4. Check that the correct BASELINE_PACKAGE root is being passed, not the target package root.

Example fix

# before: bin/opencode is a symlink shim
$ rm -rf node_modules/<baseline-package> && pnpm install
$ node scripts/materialize-opencode-binary.mjs
Defensive patterns

Strategy: validation

Validate before calling

import { lstatSync } from 'node:fs';
const st = lstatSync(join(baselineRoot, 'bin', 'opencode'));
if (!st.isFile()) throw new Error('baseline bin/opencode must be a regular file (got symlink/dir?)');

Type guard

function isRegularFileSync(p) {
  try { return lstatSync(p).isFile(); } catch { return false; }
}

Try / catch

try {
  materializePinnedOpenCodeBinary();
} catch (err) {
  if (err.message === 'Pinned OpenCode source executable is not a regular file') {
    execSync(`pnpm install --force`);
    materializePinnedOpenCodeBinary();
  } else throw err;
}

Prevention

When it happens

Trigger: The baseline package's bin/opencode is missing or is a symlink (e.g. a package-manager bin shim), a directory, or otherwise not a regular file when materializePinnedOpenCodeBinary runs.

Common situations: A package manager installed opencode with a symlinked bin shim; the baseline package was partially installed (postinstall skipped); a broken extraction left bin/opencode as a directory.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/c19a78eec4f56192. Report an issue: GitHub.