can1357/oh-my-pi · error

Host file does not exist: ${hostPath}

Error message

Host file does not exist: ${hostPath}

What it means

VibemonSandbox.copyTo streams a host file into the guest. Before piping, it checks Bun.file(hostPath).exists() and throws this error if the source file is absent, so the guest never receives an empty/partial file silently.

Source

Thrown at packages/metaharness/src/tb/vmon.ts:248

	/** Run a captured shell command inside the guest. */
	async exec(command: string, opts: VmonExecOptions = {}): Promise<VmonCommandResult> {
		const result = await this.#sandbox.run(["sh", "-c", command], {
			env: { ...this.#env, HOME: this.home, ...opts.env },
			workdir: opts.cwd === null ? null : (opts.cwd ?? this.workdir),
			timeout: opts.timeoutSec,
		});
		return {
			exitCode: result.exit,
			stdout: decodeBase64(result.stdout_b64),
			stderr: decodeBase64(result.stderr_b64),
		};
	}

	/** Stream one host file into the guest without a gRPC message-size copy. */
	async copyTo(hostPath: string, guestPath: string): Promise<void> {
		const file = Bun.file(hostPath);
		if (!(await file.exists())) throw new Error(`Host file does not exist: ${hostPath}`);
		const result = await this.#pipeInput(
			file,
			[
				"sh",
				"-c",
				`mkdir -p ${quoteGuestShell(path.posix.dirname(guestPath))} && cat > ${quoteGuestShell(guestPath)}`,
			],
			900,
		);
		if (result.exitCode !== 0) throw commandError(`Uploading ${hostPath} to ${this.name}:${guestPath}`, result);
	}

	/** Stream a host directory as a gzip-compressed tar archive into the guest. */
	async copyDirectory(hostDir: string, guestDir: string): Promise<void> {
		const archive = await archiveDirectory(hostDir);
		const result = await this.#pipeInput(
			archive,
			["sh", "-c", `mkdir -p ${quoteGuestShell(guestDir)} && tar xzf - -C ${quoteGuestShell(guestDir)}`],

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the hostPath exists (ls the path) before calling copyTo
  2. Build the agent binary/entrypoint first if installAgent depends on a build artifact
  3. Fix the binaries/entrypoint configuration that produced the wrong path
  4. Check for platform-specific path issues when running on a different OS

Example fix

// before
await vm.copyTo(path.join(binaries.agent, "entry"), "/opt/agent/entry");
// after: fail early with a clear message
if (!existsSync(agentEntry)) throw new Error(`Build agent first: ${agentEntry} missing`);
await vm.copyTo(agentEntry, "/opt/agent/entry");
Defensive patterns

Strategy: validation

Validate before calling

const file = Bun.file(hostPath);
if (!(await file.exists())) {
  throw new Error(`Refusing to copyTo: missing host file ${hostPath} (build it first?)`);
}
await vm.copyTo(hostPath, guestPath);

Try / catch

try {
  await vm.copyTo(hostPath, guestPath);
} catch (err) {
  if (String(err.message).startsWith("Host file does not exist")) {
    throw new Error(`${err.message} — run the agent build step before installAgent`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling copyTo with a hostPath that does not exist on the host — e.g. installAgent referencing an agent entrypoint binary path that was never built or is misconfigured.

Common situations: Forgetting to build the agent binary before installing; a wrong binaries path in opts; typos or platform-specific paths (Windows vs POSIX) pointing at a non-existent file.

Related errors


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