google-gemini/gemini-cli · error · Error

Workspace path ${resolvedPath} is outside the allowed root d

Error message

Workspace path ${resolvedPath} is outside the allowed root directory

What it means

Thrown by validateWorkspacePath when the resolved workspace path does not lie under the allowed root. The allowed root is CODER_AGENT_ALLOWED_ROOT if set, otherwise homedir() in production (or the filesystem root / the tmpdir in test environments). path.relative(allowedRoot, resolvedPath) starting with '..' or being absolute means the workspace escaped the sandbox.

Source

Thrown at packages/a2a-server/src/config/config.ts:469

        );
      } else {
        throw err;
      }
    }

    const isTestEnv =
      process.env['VITEST'] === 'true' ||
      process.env['NODE_ENV'] === 'test' ||
      process.argv.some((arg) => arg.includes('vitest')) ||
      resolvedPath.startsWith(resolveToRealPath(tmpdir()));

    const allowedRoot = resolveToRealPath(
      getEnv('CODER_AGENT_ALLOWED_ROOT') ||
        (isTestEnv ? path.parse(resolvedPath).root : homedir()),
    );
    const relative = path.relative(allowedRoot, resolvedPath);
    if (relative.startsWith('..') || path.isAbsolute(relative)) {
      throw new Error(
        `Workspace path ${resolvedPath} is outside the allowed root directory`,
      );
    }

    let stats: fs.Stats;
    try {
      stats = await fs.promises.stat(resolvedPath);
    } catch (err: unknown) {
      if (
        err &&
        typeof err === 'object' &&
        'code' in err &&
        err.code === 'ENOENT'
      ) {
        if (isTestEnv) {
          await fs.promises.mkdir(resolvedPath, { recursive: true });
          stats = await fs.promises.stat(resolvedPath);
        } else {

View on GitHub (pinned to 5024443c72)

Solutions

  1. Set CODER_AGENT_ALLOWED_ROOT to a directory that contains the workspace (e.g. the repo root or /).
  2. Move the workspace under the user's home directory.
  3. If using symlinks, ensure the link target is within the allowed root.
  4. In test/CI, confirm NODE_ENV=test or VITEST=true is set so the test-env branch (root allowed root) applies.

Example fix

# before
export CODER_AGENT_WORKSPACE_PATH=/workspace/myproj
# throws: outside allowed root (default homedir)

# after
export CODER_AGENT_ALLOWED_ROOT=/workspace
export CODER_AGENT_WORKSPACE_PATH=/workspace/myproj
Defensive patterns

Strategy: validation

Validate before calling

import path from 'node:path';
import { homedir } from 'node:os';

function assertWorkspaceAllowed(workspace: string) {
  const root = process.env['CODER_AGENT_ALLOWED_ROOT'] || homedir();
  const rel = path.relative(root, path.resolve(workspace));
  if (rel.startsWith('..') || path.isAbsolute(rel)) {
    throw new Error(`Workspace ${workspace} outside allowed root ${root}. Set CODER_AGENT_ALLOWED_ROOT.`);
  }
}

Prevention

When it happens

Trigger: CODER_AGENT_WORKSPACE_PATH resolves to a directory outside the user's home and CODER_AGENT_ALLOWED_ROOT is unset; symlink resolution (resolveToRealPath) dereferences a workspace symlink to a path outside the allowed root; allowed root misconfigured to a parent that doesn't contain the workspace.

Common situations: CI runner whose home is /root but the checkout lives in /workspace; Docker container where the workspace is mounted outside the default home; developer pointing at /tmp/myproj without setting CODER_AGENT_ALLOWED_ROOT in non-test mode.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/e08d2985b0d3ecd8. Report an issue: GitHub.