langchain-ai/deepagents · error · ValueError

Path must start with one of {allowed_prefixes}: {path}

Error message

Path must start with one of {allowed_prefixes}: {path}

What it means

validate_path enforces an allowlist of path prefixes. If the normalized path does not start with any of the configured allowed_prefixes, a ValueError is raised, keeping all backend operations confined to permitted directories (e.g. the agent workspace root).

Source

Thrown at libs/deepagents/deepagents/backends/utils.py:722

    # Reject Windows absolute paths (e.g., C:\..., D:/...)
    if re.match(r"^[a-zA-Z]:", path):
        msg = f"Windows absolute paths are not supported: {path}. Please use virtual paths starting with / (e.g., /workspace/file.txt)"
        raise ValueError(msg)

    normalized = os.path.normpath(path)
    normalized = normalized.replace("\\", "/")

    if not normalized.startswith("/"):
        normalized = f"/{normalized}"

    # Defense-in-depth: verify normpath didn't produce traversal
    if ".." in normalized.split("/"):
        msg = f"Path traversal detected after normalization: {path} -> {normalized}"
        raise ValueError(msg)

    if allowed_prefixes is not None and not any(normalized.startswith(prefix) for prefix in allowed_prefixes):
        msg = f"Path must start with one of {allowed_prefixes}: {path}"
        raise ValueError(msg)

    return normalized


def _normalize_path(path: str | None) -> str:
    """Normalize a path to canonical form.

    Converts path to absolute form starting with /, removes trailing slashes
    (except for root), and validates that the path is not empty.

    Args:
        path: Path to normalize (None defaults to "/")

    Returns:
        Normalized path starting with / (without trailing slash unless it's root)

    Raises:
        ValueError: If path is invalid (empty string after strip)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use a path starting with one of the allowed prefixes (they are listed in the error message).
  2. Update backend configuration to include the intended root in allowed_prefixes.
  3. Convert relative paths to absolute paths under the allowed root before calling.
  4. Catch ValueError and prompt the user/agent to retry with a path inside the permitted root.

Example fix

// before
backend.read("/etc/hosts")  # prefix not allowed
// after
backend.read("/workspace/notes/hosts_copy.txt")  # inside allowed prefix
Defensive patterns

Strategy: validation

Validate before calling

def is_within_allowed(path: str, prefixes: list[str]) -> bool:
    import posixpath
    normalized = posixpath.normpath(path)
    return any(normalized.startswith(p) for p in prefixes)

Type guard

def starts_with_prefix(path: str, prefixes: tuple[str, ...]) -> bool:
    return isinstance(path, str) and any(path.startswith(p) for p in prefixes)

Try / catch

try:
    backend.write(path, data)
except ValueError as exc:
    if str(exc).startswith("Path must start with one of"):
        return {"error": "Path outside permitted roots; choose a path inside the workspace"}
    raise

Prevention

When it happens

Trigger: Calling a backend file operation with a path outside the configured allowed prefixes — e.g. validate_path('/etc/passwd') when allowed_prefixes=['/workspace/'] — or a path like '/workspace2/x' when the prefix '/workspace' (without trailing slash) is not in the list.

Common situations: Pointing tools at files outside the sandbox root; misconfigured allowed_prefixes (e.g. missing trailing slash); agents composing absolute paths from user input that escapes the root.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/e959e5b6f8691963. Report an issue: GitHub.