From 81f598ea476cbdb80c7b17b0bbdb59fc6e4add70 Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Thu, 31 Jul 2025 18:13:50 -0500 Subject: [PATCH] fix(parameters): fix _transform_and_cache_get_parameters_response was passing positional arguments to transform_value in the wrong order, making the latter fail miserably with TransformParameterError: Unable to transform value using "the value" because value was being passed as the expected transform argument. Use keyword arguments instead and cover this with a test. --- .../utilities/parameters/base.py | 4 ++- .../utilities/parameters/ssm.py | 6 ++-- .../_boto3/test_utilities_parameters.py | 28 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/aws_lambda_powertools/utilities/parameters/base.py b/aws_lambda_powertools/utilities/parameters/base.py index 42c15e11304..2daf4bb5642 100644 --- a/aws_lambda_powertools/utilities/parameters/base.py +++ b/aws_lambda_powertools/utilities/parameters/base.py @@ -187,7 +187,9 @@ def get_multiple( raise GetParameterError(str(exc)) if transform: - values.update(transform_value(values, transform, raise_on_transform_error)) + values.update( + transform_value(value=values, transform=transform, raise_on_transform_error=raise_on_transform_error), + ) self.add_to_cache(key=key, value=values, max_age=max_age) diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index 4a1acc69227..696a80cc1c9 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -650,13 +650,13 @@ def _transform_and_cache_get_parameters_response( name = parameter["Name"] value = parameter["Value"] options = parameters[name] - transform = options.get("transform") + transform = options["transform"] # NOTE: If transform is set, we do it before caching to reduce number of operations if transform: - value = transform_value(name, value, transform, raise_on_error) # type: ignore + value = transform_value(value=value, transform=transform, raise_on_transform_error=raise_on_error) # type: ignore[assignment] - _cache_key = (name, options["transform"]) + _cache_key = (name, transform) self.add_to_cache(key=_cache_key, value=value, max_age=options["max_age"]) response[name] = value diff --git a/tests/functional/parameters/_boto3/test_utilities_parameters.py b/tests/functional/parameters/_boto3/test_utilities_parameters.py index da9422ea839..6f461c6a7c7 100644 --- a/tests/functional/parameters/_boto3/test_utilities_parameters.py +++ b/tests/functional/parameters/_boto3/test_utilities_parameters.py @@ -1114,6 +1114,34 @@ def test_ssm_provider_get_parameters_by_name_do_not_raise_on_failure(mock_name, stubber.deactivate() +def test_ssm_provider_get_parameters_by_name_do_not_raise_on_failure_transform(mock_name, mock_value, config): + success = f"/dev/{mock_name}" + fail = f"/prod/{mock_name}" + params = {success: {}, fail: {}} + param_names = list(params.keys()) + expected_value = {"value": mock_value} + stub_params = {success: json.dumps(expected_value)} + + expected_stub_response = build_get_parameters_stub(params=stub_params, invalid_parameters=[fail]) + expected_stub_params = {"Names": param_names} + + provider = parameters.SSMProvider(boto_config=config) + stubber = stub.Stubber(provider.client) + stubber.add_response("get_parameters", expected_stub_response, expected_stub_params) + stubber.activate() + + try: + ret = provider.get_parameters_by_name(parameters=params, transform="json", raise_on_error=False) + + stubber.assert_no_pending_responses() + assert ret[success] == expected_value + assert ret["_errors"] + assert len(ret["_errors"]) == 1 + assert fail not in ret + finally: + stubber.deactivate() + + def test_ssm_provider_get_parameters_by_name_do_not_raise_on_failure_with_decrypt(mock_name, config): # GIVEN one parameter requires decryption and an arbitrary SDK error occurs param = f"/{mock_name}"