FoundationAgents/MetaGPT · error · FileNotFoundError
{image_path_or_pil} not exists
Error message
{image_path_or_pil} not exists What it means
encode_image in metagpt/utils/common.py base64-encodes either a PIL.Image (in memory) or an image file from disk. For the file path branch it converts str to Path and checks .exists(); a nonexistent path raises FileNotFoundError before the file is opened.
Source
Thrown at metagpt/utils/common.py:853
if not skills_dir:
skills_dir = Path(__file__).parent.absolute()
if skill_names is None:
skill_names = [skill[:-3] for skill in os.listdir(f"{skills_dir}") if skill.endswith(".js")]
skills = [skills_dir.joinpath(f"{skill_name}.js").read_text() for skill_name in skill_names]
return skills
def encode_image(image_path_or_pil: Union[Path, Image, str], encoding: str = "utf-8") -> str:
"""encode image from file or PIL.Image into base64"""
if isinstance(image_path_or_pil, Image.Image):
buffer = BytesIO()
image_path_or_pil.save(buffer, format="JPEG")
bytes_data = buffer.getvalue()
else:
if isinstance(image_path_or_pil, str):
image_path_or_pil = Path(image_path_or_pil)
if not image_path_or_pil.exists():
raise FileNotFoundError(f"{image_path_or_pil} not exists")
with open(str(image_path_or_pil), "rb") as image_file:
bytes_data = image_file.read()
return base64.b64encode(bytes_data).decode(encoding)
def decode_image(img_url_or_b64: str) -> Image:
"""decode image from url or base64 into PIL.Image"""
if img_url_or_b64.startswith("http"):
# image http(s) url
resp = requests.get(img_url_or_b64)
img = Image.open(BytesIO(resp.content))
else:
# image b64_json
b64_data = re.sub("^data:image/.+;base64,", "", img_url_or_b64)
img_data = BytesIO(base64.b64decode(b64_data))
img = Image.open(img_data)
return img
View on GitHub (pinned to 11cdf466d0)
Solutions
- Print/verify the resolved path: Path(image_path_or_pil).resolve().
- Ensure the screenshot/creation step completed (await it) before encoding.
- Anchor relative paths to an explicit base directory instead of cwd.
- If you already hold a PIL.Image, pass the Image object directly to skip filesystem lookup.
Example fix
# before
b64 = encode_image('shot.png') # relative to unpredictable cwd
# after
from pathlib import Path
p = workspace_dir / 'shot.png'
assert p.exists()
b64 = encode_image(str(p)) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def image_encodable(p) -> bool:
return Path(p).is_file() Try / catch
try:
b64 = encode_image(path)
except FileNotFoundError:
# await/regenerate the screenshot, verify path, then retry Prevention
- Await screenshot capture fully before encoding.
- Build paths from an explicit workspace directory; never join with a possibly-None part.
- Pass the PIL.Image object directly when you already have it in memory.
When it happens
Trigger: encode_image('/tmp/shot.png') when the screenshot step failed or wrote elsewhere; relative path resolved from a different cwd; typo or wrong extension; the file is created asynchronously and isn't there yet when encode is called.
Common situations: Browser screenshot saved into a per-run workspace directory while encoding uses a bare relative name; race where the screenshot future hasn't completed; path built by joining components where one is None (producing 'None' in the path).
Related errors
- json_file: {json_file} not exist, return []
- json_file: {jsonl_file} not exist, return []
- File {path} not found.
- File {data_path} not found.
- File {path} not found
AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14).
Data as JSON: /api/errors/39ea33d255c1928c.
Report an issue: GitHub.