can1357/oh-my-pi · error

Failed to install runtime at ${runtimeDir} with ${process.ex

Error message

Failed to install runtime at ${runtimeDir} with ${process.execPath} install (exit ${exitCode}): ${output}

What it means

ensureRuntimeInstalled drives `<execPath> install` to materialize a pinned dependency set into a runtime directory. If the install subprocess exits non-zero, this error wraps the exit code and combined stdout+stderr output so the caller can see why runtime installation failed.

Source

Thrown at packages/utils/src/runtime-install.ts:398

	return new Response(stream).text();
}

async function runRuntimeInstall(runtimeDir: string): Promise<void> {
	// `process.execPath` is plain bun in source/bundle mode and the compiled
	// binary otherwise; BUN_BE_BUN makes the compiled binary act as bun.
	const proc = Bun.spawn([process.execPath, "install", "--cwd", runtimeDir, "--production"], {
		env: { ...Bun.env, BUN_BE_BUN: "1" },
		stdout: "pipe",
		stderr: "pipe",
	});
	const [stdout, stderr, exitCode] = await Promise.all([
		readPipe(proc.stdout as ReadableStream<Uint8Array> | null),
		readPipe(proc.stderr as ReadableStream<Uint8Array> | null),
		proc.exited,
	]);
	if (exitCode === 0) return;
	const output = `${stdout}\n${stderr}`.trim();
	throw new Error(
		`Failed to install runtime at ${runtimeDir} with ${process.execPath} install (exit ${exitCode}): ${output}`,
	);
}

/**
 * Materialize a pinned dependency set into `runtimeDir` (idempotent,
 * cross-process safe). Returns `runtimeDir`.
 *
 * Serialization uses the OS-backed {@link withFileLock} at
 * `${runtimeDir}.install.lock`, which the kernel releases on process death, so
 * a crashed installer cannot wedge later attempts (issue #10120). The path is
 * deliberately distinct from the legacy `${runtimeDir}.lock` mkdir directory;
 * {@link withLegacyInstallLock} atomically reserves that namespace during the
 * new install so older processes cannot cross the migration boundary.
 */
export async function ensureRuntimeInstalled(options: EnsureRuntimeInstalledOptions): Promise<string> {
	const { runtimeDir, install, onPhase, lockAttempts = 240, lockSleepMs = 250 } = options;
	let probePackage = options.probePackage;

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the `output` portion of the message — it contains the installer's own error.
  2. Delete the runtimeDir cache and retry to clear a corrupted install state.
  3. Check network/registry access and credentials (NPM_TOKEN, .npmrc).
  4. Pin/verify the runtime version supports the install command used.

Example fix

// before (stale/corrupt cache)
await ensureRuntimeInstalled(dir, manifest);
// after
await fs.rm(dir, { recursive: true, force: true });
await ensureRuntimeInstalled(dir, manifest);
Defensive patterns

Strategy: retry

Validate before calling

const probe = Bun.file(path.join(runtimeDir, 'node_modules', firstDep, 'package.json'));
if (!(await probe.exists())) {
  // will need install; verify network/registry reachability first
}

Try / catch

try {
  await ensureRuntimeInstalled(dir, manifest);
} catch (err) {
  if (String(err.message).includes('Failed to install runtime')) {
    await fs.rm(dir, { recursive: true, force: true });
    await ensureRuntimeInstalled(dir, manifest); // one clean retry
  } else throw err;
}

Prevention

When it happens

Trigger: The spawned `process.execPath install` command exits with a non-zero code — bad network during package download, invalid/broken package.json in the runtime dir, registry auth failures, or unsupported install flags on the current runtime version.

Common situations: Offline or proxied CI environments, private npm registries requiring auth, corrupted runtime cache directories, version drift where the runtime binary no longer supports the install invocation.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/8639f56b6d4ab57c. Report an issue: GitHub.