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
- Download the remote file to a local path first and pass that path
- Strip a 'file://' prefix and use the raw filesystem path
- 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
- Treat attachment URLs as things to download first, never as media paths
- Strip file:// prefixes at ingestion boundaries
- Enforce local-path inputs in your own attachment-building layer
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
- media path must be a local relative path under the outbound
- workspace.{field} must be an absolute path without traversal
- media path must not contain parent-directory traversal: {pat
- media path escapes outbound root: {path}
- allow_fs_tools must be None or a non-empty list
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/cfe9305e952d16fe.
Report an issue: GitHub.