{"record":{"id":"ff3a80d25f1ea3e3","repo":"langchain-ai/deepagents","slug":"str-exc-re-raised-from-resolve-bounded-media-pat","errorCode":null,"errorMessage":"str(exc) (re-raised from resolve_bounded_media_path)","messagePattern":"str\\(exc\\) \\(re-raised from resolve_bounded_media_path\\)","errorType":"exception","errorClass":"ChannelMediaError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/channels/base.py","lineNumber":263,"sourceCode":"        root: Optional directory that must contain the media after symlink\n            resolution.\n        max_bytes: Optional global media size cap.\n\n    Returns:\n        The validated media payload.\n\n    Raises:\n        ChannelMediaError: If the file is missing, unsupported, or too large.\n    \"\"\"\n    try:\n        path = (\n            resolve_bounded_media_path(media.path, root, require_relative=False)\n            if root is not None\n            else media.path.expanduser()\n        )\n    except ValueError as exc:\n        msg = str(exc)\n        raise ChannelMediaError(msg) from exc\n    if not path.is_file():\n        msg = f\"media file does not exist: {path}\"\n        raise ChannelMediaError(msg)\n\n    detected = _media_type(path)\n    if detected != media.media_type:\n        msg = f\"media file type {detected!r} does not match requested type {media.media_type!r}\"\n        raise ChannelMediaError(msg)\n\n    return _validate_media_size(media, path=path, max_bytes=max_bytes)\n\n\ndef message_with_media_paths(\n    message: ChannelMessage,\n    *,\n    media_paths: Sequence[str],\n    mime_types: Sequence[str] = (),\n    has_media: bool | None = None,","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/channels/base.py#L245-L281","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nvalidate_media(ChannelMedia(path=Path('/etc/passwd'), media_type='image'))\n\n# after\nvalidate_media(ChannelMedia(path=Path('outbound/logo.png').relative_to(media_root), media_type='image'))","handlingStrategy":"try-catch","validationCode":"from deepagents_talon.media import resolve_bounded_media_path\ntry:\n    resolve_bounded_media_path(media.path, root, require_relative=False)\nexcept ValueError:\n    ...  # reject before calling send_media","typeGuard":null,"tryCatchPattern":"try:\n    await channel.send_media(media)\nexcept ChannelMediaError as exc:\n    logger.warning('media path rejected: %s', exc)\n    await channel.send_text(f'Could not send attachment: {exc}')","preventionTips":["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."],"tags":["media","path-validation","security"],"backgroundTag":"path-traversal-blocked","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}