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
- Set the workspace to a real project subdirectory, not '/' (e.g. /workspace/repo).
- Verify the config/env value feeding the workspace parameter is non-empty and points at a directory containing your project.
- If running in a container, mount the project at a nested path and reference that nested path.
- 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
- Always configure workspace as a concrete project directory, never '/' or a drive root.
- Validate workspace at config-load time, before driver construction.
- In containers, mount projects at nested paths and reference those paths.
- Add a startup assertion that the workspace contains expected project files (e.g. package.json).
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
- OpenCode evals require exact version 1.18.17; received ${ver
- ${label} is not a regular file at ${canonical}.
- ${label} must be an integer between 1 and ${maximum}.
- OpenCode native backend requires an instance runtime directo
- PAPERCLIP_EVAL_MAX_CAMPAIGN_COST_USD must be a positive fini
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/f37af23df7fb0fe3.
Report an issue: GitHub.