langchain-ai/deepagents · error · ValueError

media path must be a local filesystem path: {path}

Error message

media path must be a local filesystem path: {path}

What it means

ValueError raised by resolve_bounded_media_path when the media path is not a plain local filesystem path — i.e. urlparse detects a URL scheme (http://, file://, s3://) that is not just a Windows drive letter. Remote or URI-style references are not allowed; only local paths.

Source

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

    Args:
        path: Candidate media path.
        root: Directory that must contain the media after symlink resolution.
        require_relative: Whether to reject absolute candidate paths up front.

    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):

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Download the remote file to a local path first and pass that path
  2. Strip a 'file://' prefix and use the raw filesystem path
  3. Pass a relative path under the outbound root

Example fix

// before
resolve_bounded_media_path(Path("https://cdn.example.com/img.png"), root)
// after
local = download("https://cdn.example.com/img.png")  # returns Path under outbound root
resolve_bounded_media_path(local, root)
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
raw = str(path)
if urlparse(raw).scheme and not PureWindowsPath(raw).drive:
    raise ValueError(f"must be a local path, not a URI: {raw}")

Type guard

def is_local_path(p: Path) -> bool:
    raw = str(p)
    return not urlparse(raw).scheme or bool(PureWindowsPath(raw).drive)

Try / catch

try:
    resolved = resolve_bounded_media_path(path, root)
except ValueError as exc:
    logger.error("Bad media path: %s", exc)
    return None

Prevention

When it happens

Trigger: Passing 'https://cdn.example.com/img.png', 'file:///tmp/a.png', or 's3://bucket/x.png' as the media path.

Common situations: Reusing an attachment URL from an earlier API response instead of a local file; copying a URI from docs; confusing cloud storage paths with local paths.

Related errors


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