{"record":{"id":"ee0d75f4c594150b","repo":"invoke-ai/InvokeAI","slug":"mode-request-mode-requires-a-mask-image-for-r","errorCode":null,"errorMessage":"Mode '{request.mode}' requires a mask image for {request.model.name}","messagePattern":"Mode '(.+?)' requires a mask image for (.+?)","errorType":"exception","errorClass":"ExternalProviderCapabilityError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/external_generation/external_generation_default.py","lineNumber":147,"sourceCode":"            aspect_ratio = _format_aspect_ratio(request.width, request.height)\n            if aspect_ratio not in capabilities.allowed_aspect_ratios:\n                size_ratio = None\n                if capabilities.aspect_ratio_sizes:\n                    size_ratio = _ratio_for_size(request.width, request.height, capabilities.aspect_ratio_sizes)\n                if size_ratio is None or size_ratio not in capabilities.allowed_aspect_ratios:\n                    ratio_label = size_ratio or aspect_ratio\n                    raise ExternalProviderCapabilityError(\n                        f\"{request.model.name} does not support aspect ratio {ratio_label}\"\n                    )\n\n        required_modes = capabilities.input_image_required_for or [\"img2img\", \"inpaint\"]\n        if request.mode in required_modes and request.init_image is None:\n            raise ExternalProviderCapabilityError(\n                f\"Mode '{request.mode}' requires an init image for {request.model.name}\"\n            )\n\n        if request.mode == \"inpaint\" and request.mask_image is None:\n            raise ExternalProviderCapabilityError(\n                f\"Mode '{request.mode}' requires a mask image for {request.model.name}\"\n            )\n\n    def _drop_unsupported_capabilities(self, request: ExternalGenerationRequest) -> ExternalGenerationRequest:\n        \"\"\"Silently drop request fields the selected model does not support so workflow-editor runs don't fail\n        when users wire them in regardless.\"\"\"\n        capabilities = request.model.capabilities\n        updates: dict[str, object] = {}\n\n        if request.seed is not None and not capabilities.supports_seed:\n            self._logger.debug(\n                \"Dropping seed for %s: model does not support seed control\",\n                request.model.name,\n            )\n            updates[\"seed\"] = None\n\n        if updates:\n            return dataclasses.replace(request, **updates)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/external_generation/external_generation_default.py#L129-L165","documentation":"InvokeAI requires a mask image whenever the generation mode is 'inpaint'. The validation in _validate_request raises ExternalProviderCapabilityError if request.mask_image is None for inpaint mode, because inpainting is undefined without a mask telling the provider which pixels to regenerate. This fails fast before any network call.","triggerScenarios":"Calling generate() with request.mode == 'inpaint' and request.mask_image is None. The init image check (620) passes but the mask check then fails.","commonSituations":"Workflow nodes wired for inpaint without a mask input; API scripts that set mode='inpaint' and an init image but forget the mask; UI paths that default to inpaint mode when a mask hasn't been drawn yet.","solutions":["Provide request.mask_image (a mask aligned with the init image) before calling generate","Switch request.mode to 'img2img' or 'txt2img' if masking is not intended","In the UI/workflow editor, connect or draw a mask for the inpaint node","Verify the mask dimensions match the init image to avoid downstream provider errors"],"exampleFix":"// before\nrequest = ExternalGenerationRequest(model=model, mode='inpaint', prompt='fix sky', init_image=img)\nresult = service.generate(request)  # raises\n// after\nrequest = ExternalGenerationRequest(model=model, mode='inpaint', prompt='fix sky', init_image=img, mask_image=mask)\nresult = service.generate(request)","handlingStrategy":"validation","validationCode":"if request.mode == 'inpaint' and request.mask_image is None:\n    raise ValueError(\"inpaint mode requires a mask image\")\n# then call generate(request)","typeGuard":"def has_mask(req) -> bool:\n    return getattr(req, 'mask_image', None) is not None","tryCatchPattern":"try:\n    result = service.generate(request)\nexcept ExternalProviderCapabilityError as e:\n    if 'mask image' in str(e):\n        request = replace(request, mode='img2img')  # degrade gracefully or prompt user for a mask\n    raise","preventionTips":["Always pair inpaint requests with a mask aligned to the init image","Validate mode/image/mask combinations client-side before generate()","In UIs, disable the inpaint action until a mask exists"],"tags":["validation","request-validation","inpainting","mask-image"],"backgroundTag":"missing-required-input","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}