From 1ff56836f519ebb727262f346eb3e1ec997cc523 Mon Sep 17 00:00:00 2001 From: RitoFactory Date: Mon, 24 Aug 2026 10:21:46 +0000 Subject: [PATCH] Fix dict idempotency missing-key detection from issue #8390 --- .../utilities/idempotency/persistence/base.py | 4 +++- .../functional/idempotency/_boto3/test_idempotency.py | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index 3d54a01f018..be0ab04ed13 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -131,7 +131,9 @@ def _get_hashed_idempotency_key(self, data: dict[str, Any]) -> str | None: @staticmethod def is_missing_idempotency_key(data) -> bool: - if isinstance(data, (tuple, list, dict)): + if isinstance(data, dict): + return all(x is None for x in data.values()) + elif isinstance(data, (tuple, list)): return all(x is None for x in data) elif isinstance(data, (int, float, bool)): return False diff --git a/tests/functional/idempotency/_boto3/test_idempotency.py b/tests/functional/idempotency/_boto3/test_idempotency.py index e5916dba0fa..2cbed3496ea 100644 --- a/tests/functional/idempotency/_boto3/test_idempotency.py +++ b/tests/functional/idempotency/_boto3/test_idempotency.py @@ -1046,6 +1046,10 @@ def test_is_missing_idempotency_key(): assert BasePersistenceLayer.is_missing_idempotency_key((None, None)) # GIVEN a dict of Nones THEN is_missing_idempotency_key is True assert BasePersistenceLayer.is_missing_idempotency_key({None: None}) + # GIVEN a dict with non-None keys and all None values THEN is_missing_idempotency_key is True + assert BasePersistenceLayer.is_missing_idempotency_key({"user": None, "order": None}) + # GIVEN a dict with a non-None value THEN is_missing_idempotency_key is False + assert BasePersistenceLayer.is_missing_idempotency_key({"user": "123", "order": None}) is False # GIVEN True THEN is_missing_idempotency_key is False assert BasePersistenceLayer.is_missing_idempotency_key(True) is False @@ -1092,7 +1096,7 @@ def test_default_no_raise_on_missing_idempotency_key( @pytest.mark.parametrize( "idempotency_config", [ - {"use_local_cache": False, "event_key_jmespath": "[body, x]"}, + {"use_local_cache": False, "event_key_jmespath": "{user: user, order: order}"}, ], indirect=True, ) @@ -1104,9 +1108,9 @@ def test_raise_on_no_idempotency_key( persistence_store.configure(idempotency_config) persistence_store.raise_on_no_idempotency_key = True assert persistence_store.use_local_cache is False - assert "body" in persistence_store.event_key_jmespath + assert "user" in persistence_store.event_key_jmespath - # WHEN getting the hashed idempotency key for an event with no `body` key + # WHEN getting the hashed idempotency key for an event with neither projected key with pytest.raises(IdempotencyKeyError) as excinfo: persistence_store._get_hashed_idempotency_key({})