Bug: idempotent functions return None on replay when the stored response is falsy (0, False, "", [], {})
Mantenedores costumam responder em até 2 dias
Avaliação
Esta issue ainda não foi avaliada.
Descrição
Expected Behaviour
When an idempotent function returns a falsy value (0, False, "", [], {}), a retry with the same payload should return that same value from the persistence store.
Current Behaviour
The first call returns the value and it is stored correctly, but every replay returns None.
IdempotencyHandler._handle_for_status reads the stored response with:
serialized_response = self.output_serializer.from_dict(response_dict) if response_dict else None
so any falsy response_dict becomes None. #8090 pointed out this line together with the write path in _get_function_response. The write path was changed to is not None, but the read path still uses a truthiness check, so the value is saved and then dropped on replay.
Code snippet
from aws_lambda_powertools.utilities.idempotency import idempotent_function
from aws_lambda_powertools.utilities.idempotency.exceptions import (
IdempotencyItemAlreadyExistsError,
IdempotencyItemNotFoundError,
)
from aws_lambda_powertools.utilities.idempotency.persistence.base import BasePersistenceLayer, DataRecord
class InMemoryPersistenceLayer(BasePersistenceLayer):
def __init__(self):
super().__init__()
self.records = {}
def _get_record(self, idempotency_key) -> DataRecord:
if idempotency_key not in self.records:
raise IdempotencyItemNotFoundError
return self.records[idempotency_key]
def _put_record(self, data_record: DataRecord) -> None:
if data_record.idempotency_key in self.records:
raise IdempotencyItemAlreadyExistsError
self.records[data_record.idempotency_key] = data_record
def _update_record(self, data_record: DataRecord) -> None:
self.records[data_record.idempotency_key] = data_record
def _delete_record(self, data_record: DataRecord) -> None:
self.records.pop(data_record.idempotency_key, None)
persistence_layer = InMemoryPersistenceLayer()
@idempotent_function(data_keyword_argument="order", persistence_store=persistence_layer)
def count_items(order):
return len(order["items"])
order = {"order_id": "o-1", "items": []}
print(count_items(order=order)) # 0
print(count_items(order=order)) # None, expected 0
I see the same with CachePersistenceLayer on a real Redis server: 0, False, "", [] and {} all come back as None on replay, while None and truthy values are returned correctly.
Possible Solution
Use is not None, matching the write path:
serialized_response = self.output_serializer.from_dict(response_dict) if response_dict is not None else None
DataRecord.response_json_as_dict() already returns None when there is no stored data, and a function that returns None is stored as null, so that case keeps returning None.
Steps to Reproduce
Run the snippet above. Any persistence layer is affected, since the check is in the shared handler.
Powertools for AWS Lambda (Python) version
latest (3.37.0, also on develop)
AWS Lambda function runtime
3.13
Packaging format used
PyPi
Debugging logs
N/A, the replay returns None without an error
- Linguagem predominante
- Python
- Estrelas
- 3.3k
- Forks
- 511
- Merge médio
- 3d 12h
- PRs com merge (30d)
- 93
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de aws-powertools/powertools-lambda-python
-
Bug: POWERTOOLS_IDEMPOTENCY_DISABLED set to an empty or non-boolean value crashes every invocationTalvez já em andamento @lechakrawarthy assumiu hoje. Abertabug good first issue help wanted idempotency
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 85/100
aws-powertools/powertools-lambda-python#8728 · 2 comentários ·
Mantenedores costumam responder em até 2 dias
-
bug good first issue help wanted idempotency
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 85/100
aws-powertools/powertools-lambda-python#8727 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
bug good first issue help wanted idempotency
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
aws-powertools/powertools-lambda-python#8726 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
bug good first issue help wanted idempotency
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 80/100
aws-powertools/powertools-lambda-python#8725 · 1 comentário ·
Mantenedores costumam responder em até 2 dias
-
Bug: with a DynamoDB composite key, DataRecord.idempotency_key is the static partition key valueTalvez já em andamento @sumedh-aerram assumiu hoje. Abertabug good first issue help wanted idempotency
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 90/100
aws-powertools/powertools-lambda-python#8724 · 2 comentários ·
Mantenedores costumam responder em até 2 dias
Todas as issues de aws-powertools/powertools-lambda-python
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
weecology/DeepForest#1445 ·
-
agent-ready priority: medium status: ready
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
melodic-software/claude-code-plugins#11864 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
PolicyEngine/policyengine-uk#2785 ·
Mantenedores costumam responder em até 2 dias
-
correction metadata
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 62/100
acl-org/acl-anthology#10724 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
use-agent-os/agent-os#3739 ·
Mantenedores costumam responder em até 1 dia