{"record":{"id":"eac9eda2757ea82b","repo":"BerriAI/litellm","slug":"amazon-nova-canvas-inpainting-requires-either-mask","errorCode":null,"errorMessage":"Amazon Nova Canvas INPAINTING requires either maskPrompt or maskImage (use OpenAI mask= for maskImage, or pass maskPrompt in optional params). See https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html","messagePattern":"Amazon Nova Canvas INPAINTING requires either maskPrompt or maskImage \\(use OpenAI mask= for maskImage, or pass maskPrompt in optional params\\)\\. See https://docs\\.aws\\.amazon\\.com/nova/latest/userguide/image-gen-req-resp-structure\\.html","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/bedrock/image_edit/amazon_nova_canvas_image_edit_transformation.py","lineNumber":111,"sourceCode":"        }\n    # Explicit taskType must be INPAINTING or omitted from here on; anything else is invalid.\n    if task_type is not None and str(task_type).strip() != \"\":\n        if task_type != \"INPAINTING\":\n            raise ValueError(\n                f\"Unsupported Amazon Nova Canvas taskType: {task_type!r}. \"\n                \"Use BACKGROUND_REMOVAL, OUTPAINTING, IMAGE_VARIATION, INPAINTING, \"\n                \"or omit taskType for automatic routing (mask → INPAINTING, else IMAGE_VARIATION).\"\n            )\n    if mask_b64 is not None or mask_prompt is not None or task_type == \"INPAINTING\":\n        in_params: Final[dict[str, Any]] = {\"image\": image_b64, \"text\": text}\n        if mask_prompt is not None:\n            in_params[\"maskPrompt\"] = mask_prompt\n        elif mask_b64 is not None:\n            in_params[\"maskImage\"] = mask_b64\n        if negative_text is not None:\n            in_params[\"negativeText\"] = negative_text\n        if \"maskPrompt\" not in in_params and \"maskImage\" not in in_params:\n            raise ValueError(\n                \"Amazon Nova Canvas INPAINTING requires either maskPrompt or maskImage \"\n                \"(use OpenAI mask= for maskImage, or pass maskPrompt in optional params). \"\n                \"See https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html\"\n            )\n        return {\"taskType\": \"INPAINTING\", \"inPaintingParams\": in_params}\n    var_params: Final[dict[str, Any]] = {\n        \"images\": [image_b64],\n        \"text\": text,\n    }\n    if negative_text is not None:\n        var_params[\"negativeText\"] = negative_text\n    if similarity_strength is not None:\n        var_params[\"similarityStrength\"] = similarity_strength\n    return {\n        \"taskType\": \"IMAGE_VARIATION\",\n        \"imageVariationParams\": var_params,\n    }\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/bedrock/image_edit/amazon_nova_canvas_image_edit_transformation.py#L93-L129","documentation":"Inside the INPAINTING branch (entered when taskType=='INPAINTING' or when a mask/maskPrompt is present), the builder must put maskPrompt or maskImage into inPaintingParams. If neither survived parameter extraction, it raises ValueError pointing at the AWS Nova docs, since Bedrock rejects inpainting without a mask.","triggerScenarios":"taskType='INPAINTING' with neither mask= nor maskPrompt supplied; or auto-routing selected INPAINTING via a truthy-but-empty mask edge (e.g. mask consumed earlier and produced None b64).","commonSituations":"Assuming Nova inpainting infers the mask from the prompt like some OpenAI workflows; passing mask as a form field the proxy didn't forward; mask file present but named differently than 'mask'.","solutions":["Pass maskPrompt in optional params: {\"taskType\": \"INPAINTING\", \"maskPrompt\": \"...\"}.","Or send the mask image under the OpenAI 'mask' file field so LiteLLM encodes it as maskImage.","If you have no mask, use taskType='IMAGE_VARIATION' or omit taskType."],"exampleFix":"# before\nlitellm.image_edit(model=\"bedrock/nova-canvas\", image=img,\n                  prompt=\"remove object\", taskType=\"INPAINTING\")  # ValueError\n# after\nlitellm.image_edit(model=\"bedrock/nova-canvas\", image=img,\n                  prompt=\"remove object\", taskType=\"INPAINTING\",\n                  mask=open(\"mask.png\", \"rb\"))","handlingStrategy":"validation","validationCode":"def validate_inpainting(params: dict, mask_present: bool) -> None:\n    if params.get(\"taskType\") == \"INPAINTING\" and not (\n        mask_present or params.get(\"maskPrompt\")\n    ):\n        raise ValueError(\"INPAINTING needs mask= file or maskPrompt\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never send INPAINTING without mask or maskPrompt — Bedrock requires it downstream anyway.","Name the multipart mask field exactly 'mask'.","If no mask exists, choose IMAGE_VARIATION or omit taskType."],"tags":["bedrock","nova-canvas","image-edit","inpainting","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}