mastra-ai/mastra · error

Path escapes workspace root: ${inputPath}

Error message

Path escapes workspace root: ${inputPath}

What it means

This sandboxed filesystem resolves every user-supplied path against the workspace root and refuses anything that lexically normalizes outside it. The library throws this to enforce the sandbox boundary: even a path like `a/../../etc/passwd` or an absolute path pointing at a sibling directory is rejected before any shell command runs. It is a deliberate security guard, not a bug.

Source

Thrown at mastracode/sdk/src/agents/sandbox-filesystem.ts:165

   * Accepts both workspace-relative paths (`src/foo.ts`, `/src/foo.ts`) and
   * absolute sandbox paths that already live under the workdir — the agent's
   * prompt advertises the workdir as its working directory, so tools are
   * routinely called with fully-qualified paths like `<workdir>/src/foo.ts`.
   */
  private resolveAgainst(basePath: string, inputPath: string): string {
    const base = posixPath.normalize(basePath);
    const normalizedInput = posixPath.normalize(inputPath);
    const rel =
      normalizedInput === base
        ? ''
        : normalizedInput.startsWith(`${base}/`)
          ? normalizedInput.slice(base.length + 1)
          : inputPath.startsWith('/')
            ? inputPath.slice(1)
            : inputPath;
    const resolved = posixPath.normalize(posixPath.join(base, rel));
    if (resolved !== base && !resolved.startsWith(`${base}/`)) {
      throw new Error(`Path escapes workspace root: ${inputPath}`);
    }
    return resolved;
  }

  resolveAbsolutePath(inputPath: string): string | undefined {
    // Sync interface: a lazy workdir that has not resolved yet has no
    // absolute form to offer.
    if (!this.resolvedBase) return undefined;
    return this.resolveAgainst(this.resolvedBase, inputPath);
  }

  // ── Command helper ─────────────────────────────────────────────────────

  private async exec(script: string): Promise<SandboxCommandResult> {
    return this.sandbox.executeCommand('sh', ['-c', script], { timeout: COMMAND_TIMEOUT_MS });
  }

  /**

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Remove `..` segments or rewrite the path so it resolves inside the workspace root
  2. If the target genuinely lives outside the root, move it into the workspace or reconfigure the sandbox workdir to encompass it
  3. Normalize/validate caller-supplied paths (e.g. path.resolve then checking containment) before passing them to the sandbox API

Example fix

// before
await fs.resolveAsync('../outside/secret.txt'); // throws
// after
await fs.resolveAsync('outside/secret.txt'); // stays within workspace root
Defensive patterns

Strategy: validation

Validate before calling

import path from 'node:path';
export function isInsideRoot(root: string, input: string): boolean {
  const resolvedInput = path.resolve(root, input);
  const resolvedRoot = path.resolve(root);
  return resolvedInput === resolvedRoot || resolvedInput.startsWith(resolvedRoot + path.sep);
}
if (!isInsideRoot(WORKSPACE_ROOT, userInput)) throw new Error('Path must stay inside the workspace root');

Type guard

function isSafeWorkspacePath(p: string): boolean {
  const norm = path.posix.normalize(p.replace(/^\//, ''));
  return !norm.startsWith('..') && norm !== '..' && !path.posix.isAbsolute(norm);
}

Try / catch

try {
  const resolved = await fs.resolveAsync(inputPath);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Path escapes workspace root')) {
    // reject/ask for corrected path; never retry with the same input
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling resolveAsync, resolveAbsolutePath, or any file operation built on resolveAgainst with a path containing `..` segments that escape the root (e.g. `../secrets.txt`, `a/../../x`), or an absolute path that does not fall under the configured workspace root base.

Common situations: Passing an absolute host path (e.g. `/home/user/file`) into a sandbox whose root is a different directory; joining a workspace-external temp dir; resolving symlink-like or user-provided paths that contain `..`; configuring the sandbox workdir lower in the tree than the paths the agent tries to touch.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/7f0be3f4d11b5023. Report an issue: GitHub.