Skip to content

fix(idempotency): treat empty or unparsable POWERTOOLS_IDEMPOTENCY_DISABLED as not disabled - #8734

Open
lechakrawarthy wants to merge 1 commit into
aws-powertools:developfrom
lechakrawarthy:fix/idempotency-disabled-env
Open

lechakrawarthy wants to merge 1 commit into
aws-powertools:developfrom
lechakrawarthy:fix/idempotency-disabled-env

Conversation

@lechakrawarthy

Copy link
Copy Markdown

Issue number:

closes #8728

Summary

Changes

idempotent and idempotent_function both called strtobool(os.getenv("POWERTOOLS_IDEMPOTENCY_DISABLED", "false")), and strtobool raises ValueError for an empty string or any non-boolean value, so every invocation crashed before the handler ran.

  • Added _is_idempotency_disabled() in idempotency.py. It resolves the variable once and returns False for values strtobool rejects, with a debug log saying the value was ignored. Recognised values behave exactly as before.
  • Both decorators now use the helper.
  • I did not use resolve_truthy_env_var_choice from shared/functions.py: it calls the same strtobool and raises the same way, and changing it would change behaviour for every utility that uses it.

Tests

Added test_idempotency_disabled_envvar_empty_or_unparsable in tests/functional/idempotency/_boto3/test_idempotency.py, next to the existing env var tests. It runs both decorators with "", " ", "maybe" and the variable unset, and checks the functions return their result and the persistence layer is still called (idempotency stays on). The existing truthy and falsy cases are unchanged and still pass.

Verification

Ran locally on Windows (uv sync --locked --extra all --extra redis --extra datamasking; the valkey extra does not build on Windows).

New test on develop, before the fix:

FAILED ...::test_idempotency_disabled_envvar_empty_or_unparsable[]
FAILED ...::test_idempotency_disabled_envvar_empty_or_unparsable[ ]
FAILED ...::test_idempotency_disabled_envvar_empty_or_unparsable[maybe]
E       ValueError: invalid truth value 'maybe'
=========== 3 failed, 1 passed, 114 deselected, 1 warning in 15.51s ===========

With the fix:

uv run pytest tests/unit/idempotency tests/functional/idempotency -q
================ 206 passed, 88 warnings in 377.74s (0:06:17) =================

uv run mypy aws_lambda_powertools/utilities/idempotency/idempotency.py
Success: no issues found in 1 source file

After that run I split the debug log string over two lines (ruff E501) and re-ran the env var tests, ruff and mypy:

uv run pytest tests/functional/idempotency/_boto3/test_idempotency.py -q -k disabled
============== 11 passed, 107 deselected, 10 warnings in 31.08s ===============

uv run ruff format --check <changed files>
2 files already formatted

uv run ruff check <changed files>
All checks passed!

uv run mypy aws_lambda_powertools/utilities/idempotency/idempotency.py
Success: no issues found in 1 source file

AI disclosure

This change was made with the help of an AI coding assistant. I ran the commands above and the output is pasted as seen.

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

@lechakrawarthy
lechakrawarthy requested a review from a team as a code owner November 1, 2026 10:16
@boring-cyborg boring-cyborg Bot added the tests label Nov 1, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Nov 1, 2026
…SABLED as not disabled

strtobool("") raised ValueError, so an empty or non-boolean value crashed
every invocation before the handler ran. Resolve the variable once in a
helper that returns False (with a debug log) for values strtobool rejects,
and use it in both idempotent and idempotent_function.
@lechakrawarthy
lechakrawarthy force-pushed the fix/idempotency-disabled-env branch from 308f637 to 364b675 Compare November 1, 2026 10:27

This branch has not been deployed

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

Labels

size/M Denotes a PR that changes 30-99 lines, ignoring generated files. tests

1 participant