From 4b10577bc64881379b28287f7e5a894b1a7ed707 Mon Sep 17 00:00:00 2001 From: Tai An Date: Sun, 6 Sep 2026 09:21:35 -0700 Subject: [PATCH] fix(aws): repair the malformed %s in the tag-key "not permitted" message `validate_aws_tag` raises for a tag key that does not match `PERMITTED`, but the template reads `Key *s* is not permitted...` instead of `Key *%s* ...`. With only one conversion specifier left for two arguments, the `%` operation raises `TypeError: not all arguments converted during string formatting` before `MetaflowException` is ever constructed. The value branch three lines below is the correct copy (`Value *%s* is not permitted. Tags must match pattern: %s`), as are the two length checks above. Reachable from `--tag` on both AWS Batch (`batch_decorator.py`) and Step Functions (`step_functions_cli.py`): any tag key whose first character is outside `[A-Za-z0-9\s+\-=._:/@]` hits it and the user sees an opaque TypeError instead of the intended message. The existing parametrised test never passes a non-permitted key and swallows bare `Exception`, so the branch was invisible to it; the added test asserts the rendered message for both the key and the value branch. Signed-off-by: Tai An --- metaflow/plugins/aws/aws_utils.py | 2 +- test/unit/test_aws_util.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/metaflow/plugins/aws/aws_utils.py b/metaflow/plugins/aws/aws_utils.py index 96143c67c70..c3766f6e40a 100644 --- a/metaflow/plugins/aws/aws_utils.py +++ b/metaflow/plugins/aws/aws_utils.py @@ -219,7 +219,7 @@ def validate_aws_tag(key: str, value: str): if not re.match(PERMITTED, key): raise MetaflowException( - "Key *s* is not permitted. Tags must match pattern: %s" % (key, PERMITTED) + "Key *%s* is not permitted. Tags must match pattern: %s" % (key, PERMITTED) ) if not re.match(PERMITTED, value): raise MetaflowException( diff --git a/test/unit/test_aws_util.py b/test/unit/test_aws_util.py index a212996c4eb..1398b0729d8 100644 --- a/test/unit/test_aws_util.py +++ b/test/unit/test_aws_util.py @@ -1,5 +1,6 @@ import pytest +from metaflow.exception import MetaflowException from metaflow.plugins.aws.aws_utils import validate_aws_tag @@ -37,3 +38,17 @@ def test_validate_aws_tag(key, value, should_raise): did_raise = True assert did_raise == should_raise + + +@pytest.mark.parametrize( + "key, value, expected_prefix", + [ + ("#not-permitted", "ok", "Key *#not-permitted* is not permitted."), + ("ok", "#not-permitted", "Value *#not-permitted* is not permitted."), + ], +) +def test_validate_aws_tag_not_permitted_message(key, value, expected_prefix): + with pytest.raises(MetaflowException) as exc_info: + validate_aws_tag(key, value) + + assert str(exc_info.value).startswith(expected_prefix)