paperclipai/paperclip · error

OpenCode working directory must not be a filesystem root

Error message

OpenCode working directory must not be a filesystem root

What it means

The OpenCode server driver validates that the workspace/working directory passed to it resolves to a real subdirectory, not a filesystem root. It resolves the given path and compares it with its own parent via dirname; if they are equal (or the value is blank), the path is a root like '/' and the driver refuses to run an agent there. This prevents catastrophic sandbox escapes where the agent could operate on the entire filesystem.

Source

Thrown at packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts:2490

  ];
}

function sessionRoot(
  runtimeDirectory: string,
  normalizedSessionId: string,
): string {
  const safe = normalizedSessionId
    .replace(/[^a-zA-Z0-9._-]/g, "_")
    .slice(0, 120);
  if (!safe || safe === "." || safe === "..")
    throw new Error("Invalid normalized OpenCode session id");
  return join(resolve(runtimeDirectory), safe);
}

function validateWorkspace(value: string): string {
  const cwd = resolve(value);
  if (!value.trim() || cwd === dirname(cwd))
    throw new Error("OpenCode working directory must not be a filesystem root");
  return cwd;
}

function validModel(value: string): boolean {
  const slash = value.indexOf("/");
  return slash > 0 && slash < value.length - 1;
}

function compareVersion(left: string, right: string): number {
  const a = left.split(".").map(Number);
  const b = right.split(".").map(Number);
  for (let index = 0; index < 3; index += 1) {
    if (a[index] !== b[index]) return (a[index] ?? 0) - (b[index] ?? 0);
  }
  return 0;
}

function bounded(value: unknown): Record<string, unknown> {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Set the workspace to a real project subdirectory, not '/' (e.g. /workspace/repo).
  2. Verify the config/env value feeding the workspace parameter is non-empty and points at a directory containing your project.
  3. If running in a container, mount the project at a nested path and reference that nested path.
  4. Add your own pre-check resolve(value) !== dirname(resolve(value)) before constructing the driver to fail with a clearer message.

Example fix

// before
const driver = new OpenCodeServerDriver({ workspace: '/' });
// after
const driver = new OpenCodeServerDriver({ workspace: '/workspace/my-project' });
Defensive patterns

Strategy: validation

Validate before calling

import { resolve, dirname } from 'node:path';
function isRootWorkspace(value: string): boolean {
  const cwd = resolve(value);
  return !value.trim() || cwd === dirname(cwd);
}
if (isRootWorkspace(config.workspace)) throw new Error(`workspace must be a subdirectory, got: ${config.workspace}`);

Type guard

function isRealWorkspace(value: string): value is string {
  const cwd = resolve(value);
  return value.trim().length > 0 && cwd !== dirname(cwd) && existsSync(cwd);
}

Try / catch

try {
  const driver = new OpenCodeServerDriver({ workspace: cfg.workspace });
} catch (err) {
  if ((err as Error).message.includes('must not be a filesystem root')) {
    throw new ConfigError(`Invalid workspace '${cfg.workspace}': use a project subdirectory, not a root path`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the OpenCode driver with workspace '/', '', ' ', or any path whose resolve() equals its dirname (e.g. '/' on POSIX, 'C:\\' on Windows); passing an unconfigured or defaulted runtime workspace variable that is empty so resolve('') yields the process cwd root.

Common situations: Misconfigured env vars like WORKSPACE=/ in containers where the mount point is the container root; docker run with workspace mounted at /; template substitution leaving an empty workspace string; forgetting to set a project subdirectory when launching the driver programmatically.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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