Skip to content

Bug: a result that is not JSON serializable leaves the idempotency record stuck as INPROGRESS #8721

Open

Description

@leandrodamascena

Warning

For contributors, human or agent. Comment here to claim this issue and wait for the assignment before opening a PR; if two PRs show up, the assignee's stays. AI-assisted work is welcome, say so in the PR and tell us how you verified it: run the tests yourself and paste what you saw, do not describe runs you did not do. Read AGENTS.md first, it has the commands and the rules the CI enforces. This goes into 3.41.0.

Expected Behaviour

If the decorated function returns something the persistence layer cannot save, the invocation fails with IdempotencyPersistenceLayerError and the INPROGRESS record is removed, so the next call with the same payload runs the function again. That is what already happens when the function itself raises.

Current Behaviour

save_success fails (for example on a datetime, set or bytes in the result), the error is wrapped as IdempotencyPersistenceLayerError, and the INPROGRESS record stays. Every following call with the same payload gets IdempotencyAlreadyInProgressError until the in-progress expiry, and without register_lambda_context there is no in-progress expiry, so the key is locked for expires_after_seconds (one hour by default).

Code snippet

from datetime import datetime
from aws_lambda_powertools.utilities.idempotency import IdempotencyConfig, idempotent_function
from aws_lambda_powertools.utilities.idempotency.persistence.redis import CachePersistenceLayer

layer = CachePersistenceLayer(client=redis_client)

@idempotent_function(data_keyword_argument="order", persistence_store=layer, config=IdempotencyConfig(event_key_jmespath="id"))
def handler(order):
    return {"created": datetime(2026, 1, 1)}

handler(order={"id": 1})  # IdempotencyPersistenceLayerError: Object of type datetime is not JSON serializable
handler(order={"id": 1})  # IdempotencyAlreadyInProgressError, and it stays like this for an hour

Same with DynamoDBPersistenceLayer; the in-memory layer used in the tests reproduces it too.

Possible Solution

In aws_lambda_powertools/utilities/idempotency/base.py, IdempotencyHandler._process: when save_success raises, call self.persistence_store.delete_record(...) before re-raising, mirroring what the exception path already does when the function raises. Add a test in tests/functional/idempotency/_boto3/test_idempotency.py with a non-serializable return: first call raises IdempotencyPersistenceLayerError, second call runs the function again instead of raising IdempotencyAlreadyInProgressError.

Item 4 of the Idempotency audit in #8603. Everything is in base.py and the existing test helpers, no AWS resources needed.

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.13

Packaging format used

PyPi

Debugging logs

No response

Activity

  1. added this to the 3.41.0 milestone on Oct 31, 2026
  2. powertools-for-aws-oss-automation commented on Oct 31, 2026

    @powertools-for-aws-oss-automation

    Note

    For those interested in contributing, please leave a comment below so that we can assign the issue to you and make sure we don't duplicate efforts. If you have any further questions, please don't hesitate to ask below or on our Discord server.

  3. sumedh-aerram commented on Oct 31, 2026

    @sumedh-aerram

    Hi, I'd like to take this one. Plan: in IdempotencyHandler._process, delete the INPROGRESS record when save_success raises, then re-raise as IdempotencyPersistenceLayerError, mirroring the path where the function itself raises. I'll add a functional test through idempotent_function showing the second call reruns the function instead of raising IdempotencyAlreadyInProgressError, and confirm it fails on develop. I'm working with an AI assistant and will say so in the PR, along with the test output from my own runs.

  4. leandrodamascena commented on Nov 1, 2026

    @leandrodamascena
    ContributorAuthor

    @sumedh-aerram it's yours, assigning you now. Go ahead with the PR, and say in the description how you ran the tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggood first issueGood for newcomershelp wantedCould use a second pair of eyes/handsidempotencyIdempotency utility

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions