{"record":{"id":"0d258366fc748768","repo":"calesthio/OpenMontage","slug":"input-file-not-found-path","errorCode":null,"errorMessage":"Input file not found: {path}","messagePattern":"Input file not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"tools/graphics/grok_image.py","lineNumber":30,"sourceCode":"\nfrom tools.base_tool import (\n    BaseTool,\n    Determinism,\n    ExecutionMode,\n    ResourceProfile,\n    RetryPolicy,\n    ToolResult,\n    ToolRuntime,\n    ToolStability,\n    ToolStatus,\n    ToolTier,\n)\n\n\ndef _file_to_data_uri(path_str: str) -> str:\n    path = Path(path_str)\n    if not path.exists():\n        raise FileNotFoundError(f\"Input file not found: {path}\")\n    mime_type, _ = mimetypes.guess_type(path.name)\n    if not mime_type:\n        mime_type = \"application/octet-stream\"\n    encoded = base64.b64encode(path.read_bytes()).decode(\"ascii\")\n    return f\"data:{mime_type};base64,{encoded}\"\n\n\ndef _normalize_image_input(url_value: str | None, path_value: str | None) -> dict[str, str] | None:\n    if url_value:\n        return {\"url\": url_value, \"type\": \"image_url\"}\n    if path_value:\n        return {\"url\": _file_to_data_uri(path_value), \"type\": \"image_url\"}\n    return None\n\n\nclass GrokImage(BaseTool):\n    name = \"grok_image\"\n    version = \"0.1.0\"","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/graphics/grok_image.py#L12-L48","documentation":"FileNotFoundError from the Grok image tool's _file_to_data_uri helper. Before calling the x.ai images API in edit mode, a local image_path argument is read, base64-encoded, and wrapped as a data: URI; if the path does not exist on disk the helper raises before any network call happens.","triggerScenarios":"Calling grok_image with image_path (or a member of image_paths) pointing to a non-existent file: typo in the path, relative path resolved against the wrong working directory, file deleted between planning and execution, or a sandboxed agent passing a path outside its workspace.","commonSituations":"Relative paths like 'assets/input.png' run from a different cwd; agent-generated paths from a prior step that never materialized; unexpanded '~' in the path (the helper uses plain Path(path_str) without expanduser).","solutions":["Verify the file exists before invoking the tool (Path(p).exists())","Use an absolute path, or resolve relative paths against a known base directory","Expand '~' explicitly: str(Path(p).expanduser().resolve())","If the file should have been produced by an earlier pipeline step, check that step's output before retrying"],"exampleFix":"// before\ninputs = {\"mode\": \"edit\", \"image_path\": \"~/pictures/cat.png\"}\n// after\nfrom pathlib import Path\np = Path(\"~/pictures/cat.png\").expanduser().resolve()\nassert p.is_file(), f\"missing input: {p}\"\ninputs = {\"mode\": \"edit\", \"image_path\": str(p)}","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef valid_image_path(p: str) -> bool:\n    path = Path(p).expanduser().resolve()\n    return path.is_file() and path.suffix.lower() in {\".png\", \".jpg\", \".jpeg\", \".webp\"}\n\nassert valid_image_path(inputs[\"image_path\"]) or \"image_url\" in inputs","typeGuard":null,"tryCatchPattern":"try:\n        result = grok_image_tool.run(inputs)\n    except FileNotFoundError as e:\n        # path missing; resolve or regenerate the input before retry","preventionTips":["Always expanduser().resolve() paths before passing them","Generate inputs and consume them in the same absolute-path namespace","Verify earlier pipeline steps produced their files before the edit call"],"tags":["grok","image-edit","file-not-found","local-file"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}