vercel/ai · error

'HarnessAgent: `sandboxConfig.workDir` must stay inside the

Error message

'HarnessAgent: `sandboxConfig.workDir` must stay inside the sandbox default working directory.'

What it means

After posix.normalize, the workDir must not be '.', '..' or start with '../' — i.e. it must stay inside the sandbox's default working directory. Escaping via '..' would let the sandbox touch files outside its designated root, so it is rejected as a safety invariant.

Source

Thrown at packages/harness/src/agent/internal/sandbox-bootstrap.ts:61

      'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.',
    );
  }
  if (workDir.includes('\\')) {
    throw new Error(
      'HarnessAgent: `sandboxConfig.workDir` must use POSIX path separators.',
    );
  }
  if (posix.isAbsolute(workDir)) {
    throw new Error('HarnessAgent: `sandboxConfig.workDir` must be relative.');
  }

  const normalized = posix.normalize(workDir);
  if (
    normalized === '.' ||
    normalized === '..' ||
    normalized.startsWith('../')
  ) {
    throw new Error(
      'HarnessAgent: `sandboxConfig.workDir` must stay inside the sandbox default working directory.',
    );
  }
  return normalized;
}

export function resolveSessionWorkDir({
  defaultWorkingDirectory,
  harnessId,
  sessionId,
  workDir,
}: {
  readonly defaultWorkingDirectory: string;
  readonly harnessId: string;
  readonly sessionId: string;
  readonly workDir?: string;
}): string {
  return joinSandboxPath({

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Change workDir to a path that stays under the default working directory, e.g. 'runs/latest' instead of '../shared'.
  2. Verify with path.posix.normalize(workDir) in your own code that the result is not '.' / '..' / '../...'.
  3. If you need data from outside, mount/copy it into the sandbox rather than traversing upward.

Example fix

// before
const workDir = '../shared-output';
// after
const workDir = 'shared-output'; // stays inside the sandbox default work dir
Defensive patterns

Strategy: validation

Validate before calling

const n = path.posix.normalize(workDir); if (n === '.' || n === '..' || n.startsWith('../')) throw new Error('workDir escapes sandbox root');

Type guard

function isContainedPath(v: string): boolean { const n = path.posix.normalize(v); return n !== '.' && n !== '..' && !n.startsWith('../'); }

Try / catch

try { await prepareSandboxForHarness({ sandboxConfig: { workDir }, harnesses }); } catch (e) { if (e.message.includes('stay inside')) { /* reject config or clamp path */ } else throw e; }

Prevention

When it happens

Trigger: Passing sandboxConfig.workDir values like '..', './..', 'a/../../etc', or any path that normalizes to a parent of the default working directory.

Common situations: Trying to share a directory from outside the work root via traversal; computing a relative path from the wrong base so the result escapes upward.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/f4e7acc12c1bf195. Report an issue: GitHub.