langchain-ai/deepagents · error · ValueError

media path must be a local relative path under the outbound

Error message

media path must be a local relative path under the outbound root: {path}

What it means

ValueError raised by resolve_bounded_media_path when the path is absolute, a Windows absolute/drive path, or starts with '~' while require_relative is set. Media must resolve within the outbound root, so home-expanding or absolute paths are rejected.

Source

Thrown at libs/talon/deepagents_talon/media.py:220

    Returns:
        Canonical media path under `root`.

    Raises:
        ValueError: If the path is unsafe, unavailable, or escapes `root`.
    """
    raw = str(path)
    parsed = urlparse(raw)
    windows_path = PureWindowsPath(raw)
    is_windows_drive_path = bool(windows_path.drive)
    if parsed.scheme and not is_windows_drive_path:
        msg = f"media path must be a local filesystem path: {path}"
        raise ValueError(msg)
    if raw.startswith("~") or (
        require_relative
        and (path.is_absolute() or windows_path.is_absolute() or is_windows_drive_path)
    ):
        msg = f"media path must be a local relative path under the outbound root: {path}"
        raise ValueError(msg)
    if ".." in path.parts or ".." in windows_path.parts:
        msg = f"media path must not contain parent-directory traversal: {path}"
        raise ValueError(msg)

    root_resolved = root.expanduser().resolve()
    candidate_input = root_resolved / path if not path.is_absolute() else path
    try:
        candidate = candidate_input.resolve(strict=True)
    except OSError as exc:
        msg = f"media file is unavailable: {path}"
        raise ValueError(msg) from exc
    if not candidate.is_relative_to(root_resolved):
        msg = f"media path escapes outbound root: {path}"
        raise ValueError(msg)
    if not candidate.is_file():
        msg = f"media path is not a regular file: {path}"
        raise ValueError(msg)
    return candidate

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Copy the file into the outbound root directory and pass a path relative to it
  2. Pass require_relative=False only if your use case genuinely allows absolute paths (validate_media paths)
  3. Expand '~' yourself into the outbound root and re-express the path relatively

Example fix

// before
resolve_bounded_media_path(Path("~/Pictures/pic.jpg"), root)
// after
shutil.copy(Path("~/Pictures/pic.jpg").expanduser(), root / "pic.jpg")
resolve_bounded_media_path(Path("pic.jpg"), root)
Defensive patterns

Strategy: validation

Validate before calling

raw = str(path)
if raw.startswith("~") or Path(raw).is_absolute() or PureWindowsPath(raw).drive:
    raise ValueError(f"must be relative under outbound root: {raw}")

Type guard

def is_relative_media_path(p: Path) -> bool:
    raw = str(p)
    return not raw.startswith("~") and not p.is_absolute() and not PureWindowsPath(raw).is_absolute()

Try / catch

try:
    resolved = resolve_bounded_media_path(path, root)
except ValueError as exc:
    logger.error("Media path not relative to outbound root: %s", exc)
    return None

Prevention

When it happens

Trigger: Passing '/home/user/pic.jpg', 'C:\\pics\\a.png', or '~/pic.jpg' when require_relative=True (the default for outbound media).

Common situations: Using an absolute path copied from a file manager; scripts built on the developer machine using absolute paths; tilde shorthand assumed to expand.

Related errors


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