langchain-ai/deepagents · error · ChannelMediaError
str(exc) (re-raised from resolve_bounded_media_path)
Error message
str(exc) (re-raised from resolve_bounded_media_path)
What it means
`validate_media` wraps failures from `resolve_bounded_media_path` (path escaping the media root, oversized, or invalid path) by re-raising them as `ChannelMediaError` (a ValueError subclass) with the original message. This gives channel adapters a single exception type for unsafe media paths.
Source
Thrown at libs/talon/deepagents_talon/channels/base.py:263
root: Optional directory that must contain the media after symlink
resolution.
max_bytes: Optional global media size cap.
Returns:
The validated media payload.
Raises:
ChannelMediaError: If the file is missing, unsupported, or too large.
"""
try:
path = (
resolve_bounded_media_path(media.path, root, require_relative=False)
if root is not None
else media.path.expanduser()
)
except ValueError as exc:
msg = str(exc)
raise ChannelMediaError(msg) from exc
if not path.is_file():
msg = f"media file does not exist: {path}"
raise ChannelMediaError(msg)
detected = _media_type(path)
if detected != media.media_type:
msg = f"media file type {detected!r} does not match requested type {media.media_type!r}"
raise ChannelMediaError(msg)
return _validate_media_size(media, path=path, max_bytes=max_bytes)
def message_with_media_paths(
message: ChannelMessage,
*,
media_paths: Sequence[str],
mime_types: Sequence[str] = (),
has_media: bool | None = None,View on GitHub (pinned to a1af029e6e)
Solutions
- Read the embedded message from `resolve_bounded_media_path` and fix the path accordingly.
- Place the file inside the configured media root and use a path relative to it.
- Clear/adjust the media root env (`DEEPAGENTS_TALON_OUTBOUND_MEDIA_DIR` or workspace) if the restriction is unintended.
- Catch `ChannelMediaError` in the adapter and report it to the user instead of crashing.
Example fix
# before
validate_media(ChannelMedia(path=Path('/etc/passwd'), media_type='image'))
# after
validate_media(ChannelMedia(path=Path('outbound/logo.png').relative_to(media_root), media_type='image')) Defensive patterns
Strategy: try-catch
Validate before calling
from deepagents_talon.media import resolve_bounded_media_path
try:
resolve_bounded_media_path(media.path, root, require_relative=False)
except ValueError:
... # reject before calling send_media Try / catch
try:
await channel.send_media(media)
except ChannelMediaError as exc:
logger.warning('media path rejected: %s', exc)
await channel.send_text(f'Could not send attachment: {exc}') Prevention
- Keep outbound media inside the configured media root directory.
- Avoid `..` segments and symlinks that escape the root.
- Pre-resolve paths with `resolve_bounded_media_path` during generation, not at send time.
When it happens
Trigger: Calling `validate_media` (directly or via a channel's `send_media`) with a media path that `resolve_bounded_media_path` rejects: absolute path where relative is required, path traversal outside the configured root, or other ValueError raised by the resolver.
Common situations: Passing an absolute path to outbound media when `DEEPAGENTS_TALON_OUTBOUND_MEDIA_DIR` is set; paths containing `..` escaping the workspace; symlinked paths resolving outside the root.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Repository root must be an absolute contained path: {root!r}
- Skill path {skill_path} resolves outside all allowed skill d
- media path must be a local filesystem path: {path}
- media path must be a local relative path under the outbound
- media path must not contain parent-directory traversal: {pat
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ff3a80d25f1ea3e3.
Report an issue: GitHub.