crewAIInc/crewAI · error · ValueError
Image file does not exist: {v}
Error message
Image file does not exist: {v} What it means
VisionTool's Pydantic input schema validates image_path_url. For non-http inputs it converts the string to a Path and checks existence; if the file is not on disk at validation time (i.e., when the tool is invoked), ValueError is raised naming the missing path.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/vision_tool/vision_tool.py:26
from pydantic import BaseModel, Field, PrivateAttr, field_validator
from crewai_tools.security.safe_path import validate_file_path
class ImagePromptSchema(BaseModel):
"""Input for Vision Tool."""
image_path_url: str = "The image path or URL."
@field_validator("image_path_url")
@classmethod
def validate_image_path_url(cls, v: str) -> str:
if v.startswith("http"):
return v
path = Path(v)
if not path.exists():
raise ValueError(f"Image file does not exist: {v}")
valid_extensions = {".jpg", ".jpeg", ".png", ".gif", ".webp"}
if path.suffix.lower() not in valid_extensions:
raise ValueError(
f"Unsupported image format. Supported formats: {valid_extensions}"
)
return v
class VisionTool(BaseTool):
"""Tool for analyzing images using vision models.
Args:
llm: Optional LLM instance to use
model: Model identifier to use if no LLM is provided
"""
View on GitHub (pinned to 754d7323be)
Solutions
- Verify the path before invoking: expand and resolve it with pathlib and check .exists().
- Use absolute paths (str(Path(p).resolve())) so CWD differences cannot break resolution.
- Mount/copy the image into the container or working directory it runs in.
- If the image is remote, pass a full http(s) URL instead, which skips the file check.
Example fix
# before
VisionTool().run(image_path_url='images/cat.jpg') # CWD mismatch -> ValueError
# after
from pathlib import Path
p = Path('images/cat.jpg').resolve()
assert p.exists(), f'missing image: {p}'
VisionTool().run(image_path_url=str(p)) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def resolve_image(p: str) -> str:
if p.startswith('http'):
return p
path = Path(p).expanduser().resolve()
if not path.is_file():
raise FileNotFoundError(f'image not found: {path}')
return str(path)
# image_path_url = resolve_image(raw_path) before calling VisionTool Type guard
from pathlib import Path
def is_local_image(v: str) -> bool:
if v.startswith('http'):
return False
p = Path(v).expanduser().resolve()
return p.is_file() and p.suffix.lower() in {'.jpg', '.jpeg', '.png', '.gif', '.webp'} Try / catch
try:
VisionTool().run(image_path_url=path)
except ValueError as e:
if 'does not exist' in str(e):
path = str(Path(path).resolve()) # fix CWD-relative path, retry once
VisionTool().run(image_path_url=path)
else:
raise Prevention
- Always pass absolute, resolved paths to VisionTool.
- Validate file existence and extension before the tool call (mirror the tool's own checks).
- Mount image directories into containers; never assume the tool's CWD matches yours.
When it happens
Trigger: Calling VisionTool.run(image_path_url='./photo.png') with a relative or absolute path that does not exist relative to the process's current working directory, or a local path while the file lives on another machine/container.
Common situations: Agents hallucinating or typo-ing file paths; relative paths breaking when the worker process has a different CWD (containers, notebooks, cron); files not yet written before the tool call; running in Docker without mounting the image directory.
Related errors
- Unsupported image format. Supported formats: {valid_extensio
- Missing required input '{name}'{suffix}
- Invalid input '{location}': {error.get('msg')}
- Expected an async readable object with async read() method
- Expected a binary file-like object with read() and seek()
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/ecfe80797fbbde8c.
Report an issue: GitHub.