{"record":{"id":"087f32d1c3a53409","repo":"langchain-ai/deepagents","slug":"media-path-is-not-a-regular-file-path","errorCode":null,"errorMessage":"media path is not a regular file: {path}","messagePattern":"media path is not a regular file: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/media.py","lineNumber":237,"sourceCode":"        msg = f\"media path must be a local relative path under the outbound root: {path}\"\n        raise ValueError(msg)\n    if \"..\" in path.parts or \"..\" in windows_path.parts:\n        msg = f\"media path must not contain parent-directory traversal: {path}\"\n        raise ValueError(msg)\n\n    root_resolved = root.expanduser().resolve()\n    candidate_input = root_resolved / path if not path.is_absolute() else path\n    try:\n        candidate = candidate_input.resolve(strict=True)\n    except OSError as exc:\n        msg = f\"media file is unavailable: {path}\"\n        raise ValueError(msg) from exc\n    if not candidate.is_relative_to(root_resolved):\n        msg = f\"media path escapes outbound root: {path}\"\n        raise ValueError(msg)\n    if not candidate.is_file():\n        msg = f\"media path is not a regular file: {path}\"\n        raise ValueError(msg)\n    return candidate\n\n\ndef _document_parts(paths: list[Path]) -> list[str]:\n    parts: list[str] = []\n    for path in paths:\n        if path.suffix.lower() not in READABLE_DOCUMENT_EXTENSIONS:\n            parts.append(f\"_(Received unsupported document attachment: {path.name}.)_\")\n            continue\n        try:\n            if path.stat().st_size > MAX_TEXT_DOCUMENT_BYTES:\n                parts.append(f\"_(Document attachment is too large to read inline: {path.name}.)_\")\n                continue\n            content = path.read_text(encoding=\"utf-8\", errors=\"replace\")\n        except OSError:\n            parts.append(f\"_(Document attachment was unavailable: {path.name}.)_\")\n            continue\n        parts.append(f\"[Content of {path.name}]:\\n{content}\")","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/media.py#L219-L255","documentation":"resolve_bounded_media_path resolves a user-supplied media path against an outbound root and then validates it. This ValueError is raised when the resolved path exists inside the allowed root but is not a regular file (e.g. a directory, FIFO, or device node), because only regular files can be safely attached as outbound channel media.","triggerScenarios":"Calling resolve_bounded_media_path (directly or via validate_media / outbound_channel_media) with a path that points to a directory, symlink-to-directory, socket, or other non-regular filesystem entry inside the outbound root.","commonSituations":"Passing a directory instead of a file path to an outbound media attachment; a build/export step left an empty directory where the file was expected; a media pipeline produced a special file (pipe/socket) instead of a regular file.","solutions":["Pass the path to an actual regular file, not a directory or special file","Check the path with `Path(p).is_file()` before calling and fix the upstream producer of the file","If a symlink is involved, resolve it (`Path.resolve()`) and confirm the target is a regular file inside the outbound root"],"exampleFix":"// before\noutbound_channel_media(channel, \"/outbound/media/attachments\")\n// after\npath = Path(\"/outbound/media/attachments/report.pdf\")\nif not path.is_file():\n    raise FileNotFoundError(f\"expected a regular file at {path}\")\noutbound_channel_media(channel, path)","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef ensure_attachable(path: str | Path, root: Path) -> Path:\n    candidate = Path(path).resolve()\n    root_resolved = root.resolve()\n    if not candidate.is_relative_to(root_resolved):\n        raise ValueError(f\"{path} escapes outbound root {root}\")\n    if not candidate.is_file():\n        raise ValueError(f\"{path} is not a regular file\")\n    return candidate\n\nensure_attachable(\"/outbound/media/report.pdf\", Path(\"/outbound/media\"))","typeGuard":"def is_regular_file_under(p: Path, root: Path) -> bool:\n    try:\n        return p.resolve().is_file() and p.resolve().is_relative_to(root.resolve())\n    except OSError:\n        return False","tryCatchPattern":null,"preventionTips":["Always attach concrete file paths, never directories or streams","Validate with is_file() and is_relative_to(root) before calling media APIs","Resolve symlinks before validation so link targets are checked"],"tags":["filesystem","validation","media"],"backgroundTag":"invalid-file-path","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}