{"record":{"id":"39ea33d255c1928c","repo":"FoundationAgents/MetaGPT","slug":"image-path-or-pil-not-exists","errorCode":null,"errorMessage":"{image_path_or_pil} not exists","messagePattern":"(.+?) not exists","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"metagpt/utils/common.py","lineNumber":853,"sourceCode":"    if not skills_dir:\n        skills_dir = Path(__file__).parent.absolute()\n    if skill_names is None:\n        skill_names = [skill[:-3] for skill in os.listdir(f\"{skills_dir}\") if skill.endswith(\".js\")]\n    skills = [skills_dir.joinpath(f\"{skill_name}.js\").read_text() for skill_name in skill_names]\n    return skills\n\n\ndef encode_image(image_path_or_pil: Union[Path, Image, str], encoding: str = \"utf-8\") -> str:\n    \"\"\"encode image from file or PIL.Image into base64\"\"\"\n    if isinstance(image_path_or_pil, Image.Image):\n        buffer = BytesIO()\n        image_path_or_pil.save(buffer, format=\"JPEG\")\n        bytes_data = buffer.getvalue()\n    else:\n        if isinstance(image_path_or_pil, str):\n            image_path_or_pil = Path(image_path_or_pil)\n        if not image_path_or_pil.exists():\n            raise FileNotFoundError(f\"{image_path_or_pil} not exists\")\n        with open(str(image_path_or_pil), \"rb\") as image_file:\n            bytes_data = image_file.read()\n    return base64.b64encode(bytes_data).decode(encoding)\n\n\ndef decode_image(img_url_or_b64: str) -> Image:\n    \"\"\"decode image from url or base64 into PIL.Image\"\"\"\n    if img_url_or_b64.startswith(\"http\"):\n        # image http(s) url\n        resp = requests.get(img_url_or_b64)\n        img = Image.open(BytesIO(resp.content))\n    else:\n        # image b64_json\n        b64_data = re.sub(\"^data:image/.+;base64,\", \"\", img_url_or_b64)\n        img_data = BytesIO(base64.b64decode(b64_data))\n        img = Image.open(img_data)\n    return img\n","sourceCodeStart":835,"sourceCodeEnd":871,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/utils/common.py#L835-L871","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"# before\nb64 = encode_image('shot.png')  # relative to unpredictable cwd\n\n# after\nfrom pathlib import Path\np = workspace_dir / 'shot.png'\nassert p.exists()\nb64 = encode_image(str(p))","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef image_encodable(p) -> bool:\n    return Path(p).is_file()","typeGuard":null,"tryCatchPattern":"try:\n    b64 = encode_image(path)\nexcept FileNotFoundError:\n    # await/regenerate the screenshot, verify path, then retry","preventionTips":["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."],"tags":["metagpt","image","base64","path","file-not-found"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}