langchain-ai/deepagents · error · ValueError

media file is unavailable: {path}

Error message

media file is unavailable: {path}

What it means

ValueError raised by resolve_bounded_media_path when resolve(strict=True) raises OSError — the file (or an intermediate symlink target) does not exist or is unreachable. The original OSError is chained as __cause__.

Source

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

        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


def _document_parts(paths: list[Path]) -> list[str]:
    parts: list[str] = []
    for path in paths:
        if path.suffix.lower() not in READABLE_DOCUMENT_EXTENSIONS:
            parts.append(f"_(Received unsupported document attachment: {path.name}.)_")
            continue
        try:
            if path.stat().st_size > MAX_TEXT_DOCUMENT_BYTES:
                parts.append(f"_(Document attachment is too large to read inline: {path.name}.)_")

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Verify the file exists at root / relative-path before calling (Path.exists() and is_file())
  2. Fix the filename/relative path typo
  3. Ensure the producer finished writing (and closed) the file before sending; check symlink targets exist

Example fix

// before
media = outbound_channel_media(ref)  # ref.path="outbox/a.png" but file not written yet
// after
path = root / ref.path
if not path.is_file():
    raise FileNotFoundError(path)
media = outbound_channel_media(ref)
Defensive patterns

Strategy: validation

Validate before calling

target = root / relative
if not target.exists():
    raise FileNotFoundError(target)
if target.is_symlink() and not target.resolve(strict=False).exists():
    raise FileNotFoundError(f"dangling symlink: {target}")

Try / catch

try:
    resolved = resolve_bounded_media_path(path, root)
except ValueError as exc:
    logger.error("Media file unavailable: %s (cause: %r)", exc, exc.__cause__)
    return None

Prevention

When it happens

Trigger: Passing a path to a file that was deleted/moved, a dangling symlink, or a path with an unreadable intermediate directory.

Common situations: Media written asynchronously and read before the write completes; typo'd filename; files cleaned up by a temp-file sweeper before send; wrong working directory assumption.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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