Skip to content

fix(idempotency): serialize Pydantic models with mode='json' for UUID/date support#8075

Merged
leandrodamascena merged 4 commits intoaws-powertools:developfrom
abhu85:fix/8065-idempotency-uuid-serialization
Apr 2, 2026
Merged

fix(idempotency): serialize Pydantic models with mode='json' for UUID/date support#8075
leandrodamascena merged 4 commits intoaws-powertools:developfrom
abhu85:fix/8065-idempotency-uuid-serialization

Conversation

@abhu85
Copy link
Copy Markdown
Contributor

@abhu85 abhu85 commented Mar 30, 2026

Issue number: closes #8065

Summary

Changes

The _prepare_data() function in aws_lambda_powertools/utilities/idempotency/base.py was calling model_dump() without specifying mode="json", which defaults to mode="python". This caused Pydantic models containing UUIDs, dates, or datetimes to fail with "Object of type UUID is not JSON serializable" error when used with @idempotent_function.

Fix: Changed data.model_dump() to data.model_dump(mode="json") to ensure proper JSON serialization of UUID, date, and datetime fields.

User experience

Before:

from uuid import UUID
from pydantic import BaseModel

class PaymentInput(BaseModel):
    payment_id: UUID
    customer_id: str

@idempotent_function(data_keyword_argument="payment", persistence_store=persistence_layer)
def process_payment(payment: PaymentInput):
    return {"status": "processed"}

# Raises: Object of type UUID is not JSON serializable

After:

# Same code now works correctly - UUID is serialized as string for idempotency key generation
process_payment(payment=PaymentInput(payment_id=uuid4(), customer_id="123"))
# Returns: {"status": "processed"}

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

…/date support

The `_prepare_data()` function was calling `model_dump()` without specifying
`mode="json"`, which defaults to `mode="python"`. This caused Pydantic models
containing UUIDs, dates, or datetimes to fail with "Object of type UUID is not
JSON serializable" when used with `@idempotent_function`.

Fixes aws-powertools#8065
@abhu85 abhu85 requested a review from a team as a code owner March 30, 2026 16:42
@abhu85 abhu85 requested a review from sdangol March 30, 2026 16:42
@boring-cyborg boring-cyborg bot added the tests label Mar 30, 2026
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 30, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 30, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 30, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 2, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 2, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @abhu85, great fix!
At glance I thought it could be a breaking change, but after inspecting the code I saw that Pydantic models with complex types (UUID, date, datetime, Decimal, Path) would already crash during JSON hashing before this fix. For models using only primitive types (str, int, float, bool), both modes produce identical output, so existing users aren't affected. Thats really nice.

I made a few changes on top of your PR:

  • Renamed test file to test_idempotency_pydantic_json_serialization.py to better reflect its scope
  • Removed _prepare_data unit tests - functional tests should go through @idempotent_function
  • Added integration tests for date, datetime, Decimal, and PurePosixPath (original only covered UUID) - All tests follow the existing pattern in test_idempotency_with_pydantic.py

Thanks a lot, approved!

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.64%. Comparing base (b716437) to head (8264fb1).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #8075   +/-   ##
========================================
  Coverage    96.64%   96.64%           
========================================
  Files          282      282           
  Lines        13791    13791           
  Branches      1102     1102           
========================================
  Hits         13329    13329           
  Misses         339      339           
  Partials       123      123           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@leandrodamascena leandrodamascena requested a review from hjgraca April 2, 2026 14:36
@leandrodamascena leandrodamascena merged commit 3f6fc29 into aws-powertools:develop Apr 2, 2026
17 checks passed
@boring-cyborg
Copy link
Copy Markdown

boring-cyborg bot commented Apr 2, 2026

Awesome work, congrats on your first merged pull request and thank you for helping improve everyone's experience!

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

Labels

size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Idempotency key in idempotent_function fails to serialize dates/UUIDs

3 participants