{"record":{"id":"2d5f54313d85735f","repo":"calesthio/OpenMontage","slug":"edit-mode-requires-image-url-image-path-or-image-u","errorCode":null,"errorMessage":"Edit mode requires image_url/image_path or image_urls/image_paths","messagePattern":"Edit mode requires image_url/image_path or image_urls/image_paths","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/graphics/grok_image.py","lineNumber":195,"sourceCode":"        extra_images.extend(\n            {\"url\": _file_to_data_uri(path), \"type\": \"image_url\"}\n            for path in (inputs.get(\"image_paths\") or [])\n        )\n\n        if primary_image or extra_images:\n            mode = \"edit\"\n\n        if mode == \"edit\":\n            endpoint = \"https://api.x.ai/v1/images/edits\"\n            if primary_image and not extra_images:\n                payload[\"image\"] = primary_image\n            else:\n                images = []\n                if primary_image:\n                    images.append(primary_image)\n                images.extend(extra_images)\n                if not images:\n                    raise ValueError(\n                        \"Edit mode requires image_url/image_path or image_urls/image_paths\"\n                    )\n                payload[\"images\"] = images\n        else:\n            endpoint = \"https://api.x.ai/v1/images/generations\"\n\n        return endpoint, payload\n\n    @staticmethod\n    def _infer_extension(url: str) -> str:\n        suffix = Path(urlparse(url).path).suffix.lower()\n        if suffix in {\".png\", \".jpg\", \".jpeg\", \".webp\"}:\n            return suffix\n        return \".png\"\n\n    @staticmethod\n    def _output_paths(output_path: str | None, count: int, extension: str) -> list[Path]:\n        if not output_path:","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/graphics/grok_image.py#L177-L213","documentation":"ValueError raised while building the x.ai request payload in edit mode. When mode == 'edit', the tool collects a primary image (image_url/image_path) plus extra images (image_urls/image_paths); if the combined list is empty there is nothing to edit and it refuses to call the endpoint.","triggerScenarios":"Calling grok_image with mode='edit' (or omitting a prompt so mode is inferred as edit) while providing neither image_url/image_path nor any of image_urls/image_paths. Also when both are None/empty strings/falsy.","commonSituations":"Agent infers edit mode from the presence of images but the image inputs were dropped from the payload; user typo like image_ur or images_path; conditional logic that only attaches images in the generation branch.","solutions":["Provide at least one input image: image_url or image_path (or the plural forms)","Check for misspelled input keys in the tool call payload","If you actually want a fresh image with no source, set mode to generation instead of edit","Log the normalized payload before submit to confirm the image inputs survived your glue code"],"exampleFix":"// before\ninputs = {\"mode\": \"edit\", \"prompt\": \"make the sky sunset-colored\"}\n// after\ninputs = {\"mode\": \"edit\", \"prompt\": \"make the sky sunset-colored\", \"image_path\": \"photo.png\"}","handlingStrategy":"validation","validationCode":"has_image = any(inputs.get(k) for k in (\"image_url\", \"image_path\", \"image_urls\", \"image_paths\"))\nassert not (inputs.get(\"mode\") == \"edit\" and not has_image), \"edit mode needs at least one image input\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enforce the edit-mode contract in your own schema before dispatch","Distinguish edit (requires source images) from generation (prompt only)","Beware auto-inferred edit mode: presence of images may flip the mode"],"tags":["grok","image-edit","validation","missing-argument"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}