From fce891e92f9a8df28397afb6bce87b4656345b0e Mon Sep 17 00:00:00 2001 From: wunianze666-netizen Date: Wed, 10 Jun 2026 01:33:52 +0800 Subject: [PATCH 1/2] fix metadata overrides with empty string values --- invokeai/app/api/extract_metadata_from_image.py | 12 +++++++++--- tests/app/test_extract_metadata_from_image.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/invokeai/app/api/extract_metadata_from_image.py b/invokeai/app/api/extract_metadata_from_image.py index 054b3cc38cc..9e7b907f11c 100644 --- a/invokeai/app/api/extract_metadata_from_image.py +++ b/invokeai/app/api/extract_metadata_from_image.py @@ -48,7 +48,9 @@ def extract_metadata_from_image( stringified_metadata: str | None = None # Use the metadata override if provided, else attempt to extract it from the image file. - metadata_raw = invokeai_metadata_override or pil_image.info.get("invokeai_metadata", None) + metadata_raw = ( + invokeai_metadata_override if invokeai_metadata_override is not None else pil_image.info.get("invokeai_metadata", None) + ) # If the metadata is present in the image file, we will attempt to parse it as JSON. When we create images, # we always store metadata as a stringified JSON dict. So, we expect it to be a string here. @@ -66,7 +68,9 @@ def extract_metadata_from_image( # We expect the workflow, if embedded in the image, to be a JSON-stringified WorkflowWithoutID. We will store it # as a string. - workflow_raw: str | None = invokeai_workflow_override or pil_image.info.get("invokeai_workflow", None) + workflow_raw: str | None = ( + invokeai_workflow_override if invokeai_workflow_override is not None else pil_image.info.get("invokeai_workflow", None) + ) # The fallback value for workflow is None. stringified_workflow: str | None = None @@ -85,7 +89,9 @@ def extract_metadata_from_image( # We expect the workflow, if embedded in the image, to be a JSON-stringified Graph. We will store it as a # string. - graph_raw: str | None = invokeai_graph_override or pil_image.info.get("invokeai_graph", None) + graph_raw: str | None = ( + invokeai_graph_override if invokeai_graph_override is not None else pil_image.info.get("invokeai_graph", None) + ) # The fallback value for graph is None. stringified_graph: str | None = None diff --git a/tests/app/test_extract_metadata_from_image.py b/tests/app/test_extract_metadata_from_image.py index 949d6df1656..2b04b8d8370 100644 --- a/tests/app/test_extract_metadata_from_image.py +++ b/tests/app/test_extract_metadata_from_image.py @@ -204,3 +204,18 @@ def test_with_no_metadata(mock_logger): assert result.invokeai_metadata is None assert result.invokeai_workflow is None assert result.invokeai_graph is None + + +def test_empty_string_overrides_do_not_fall_back_to_image_metadata(mock_logger, valid_metadata, valid_workflow, valid_graph): + mock_image = MagicMock(spec=Image.Image) + mock_image.info = { + "invokeai_metadata": valid_metadata, + "invokeai_workflow": valid_workflow, + "invokeai_graph": valid_graph, + } + + result = extract_metadata_from_image(mock_image, "", "", "", mock_logger) + + assert result.invokeai_metadata is None + assert result.invokeai_workflow is None + assert result.invokeai_graph is None From 788a63acf5788dae000897822ef8c685ef7d8863 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 27 Jun 2026 20:23:55 -0400 Subject: [PATCH 2/2] chore(backend): ruff --- invokeai/app/api/extract_metadata_from_image.py | 8 ++++++-- tests/app/test_extract_metadata_from_image.py | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/invokeai/app/api/extract_metadata_from_image.py b/invokeai/app/api/extract_metadata_from_image.py index 9e7b907f11c..642a4b1bce1 100644 --- a/invokeai/app/api/extract_metadata_from_image.py +++ b/invokeai/app/api/extract_metadata_from_image.py @@ -49,7 +49,9 @@ def extract_metadata_from_image( # Use the metadata override if provided, else attempt to extract it from the image file. metadata_raw = ( - invokeai_metadata_override if invokeai_metadata_override is not None else pil_image.info.get("invokeai_metadata", None) + invokeai_metadata_override + if invokeai_metadata_override is not None + else pil_image.info.get("invokeai_metadata", None) ) # If the metadata is present in the image file, we will attempt to parse it as JSON. When we create images, @@ -69,7 +71,9 @@ def extract_metadata_from_image( # We expect the workflow, if embedded in the image, to be a JSON-stringified WorkflowWithoutID. We will store it # as a string. workflow_raw: str | None = ( - invokeai_workflow_override if invokeai_workflow_override is not None else pil_image.info.get("invokeai_workflow", None) + invokeai_workflow_override + if invokeai_workflow_override is not None + else pil_image.info.get("invokeai_workflow", None) ) # The fallback value for workflow is None. diff --git a/tests/app/test_extract_metadata_from_image.py b/tests/app/test_extract_metadata_from_image.py index 2b04b8d8370..7a299a57b3c 100644 --- a/tests/app/test_extract_metadata_from_image.py +++ b/tests/app/test_extract_metadata_from_image.py @@ -206,7 +206,9 @@ def test_with_no_metadata(mock_logger): assert result.invokeai_graph is None -def test_empty_string_overrides_do_not_fall_back_to_image_metadata(mock_logger, valid_metadata, valid_workflow, valid_graph): +def test_empty_string_overrides_do_not_fall_back_to_image_metadata( + mock_logger, valid_metadata, valid_workflow, valid_graph +): mock_image = MagicMock(spec=Image.Image) mock_image.info = { "invokeai_metadata": valid_metadata,