Skip to content

Commit 840854d

Browse files
committed
fix: don't error on invalid FindInMap in false-condition resources
CloudFormation skips all validation for resources with false conditions, including Fn::FindInMap lookups against non-existent mapping keys. _partial_resolve_find_in_map was re-raising InvalidTemplateException for string-literal keys that don't exist in Mappings, causing SAM CLI to reject valid templates that CloudFormation would accept. Now returns the partially-resolved FindInMap form instead of erroring, matching CloudFormation's behavior. Also updated LanguageExtensionResult docstring to accurately document the no-LE path aliasing contract (expanded_template and original_template share the same reference when had_language_extensions is False). Moved templateFnInMapInWhenFalseConditionInResourceWithInvalidStringPath from ERROR_TEMPLATES_PASSING to SUCCESS_TEMPLATES_PASSING in the Kotlin compatibility tests, with expected output.
1 parent 529f1cb commit 840854d

4 files changed

Lines changed: 46 additions & 8 deletions

File tree

samcli/lib/cfn_language_extensions/api.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,14 +315,12 @@ def _partial_resolve_find_in_map(self, value: Dict[str, Any]) -> Any:
315315
try:
316316
result = self._resolver.resolve_value({"Fn::FindInMap": resolved_args})
317317
return result
318-
except InvalidTemplateException:
319-
# Re-raise - string literals that don't exist should error
320-
raise
321-
except Exception:
322-
# Other errors - return with partially resolved args
318+
except (InvalidTemplateException, Exception):
319+
# For false-condition resources, CloudFormation skips validation
320+
# entirely — including FindInMap lookups. Don't error on missing
321+
# keys; return the partially-resolved form instead.
323322
LOG.debug(
324-
"Partial-resolve Fn::FindInMap: unexpected error resolving %r; "
325-
"returning partially-resolved args",
323+
"Partial-resolve Fn::FindInMap: could not resolve %r; " "returning partially-resolved args",
326324
resolved_args,
327325
exc_info=True,
328326
)

samcli/lib/cfn_language_extensions/sam_integration.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class LanguageExtensionResult:
4747
All template fields are independent deep copies. Callers may mutate
4848
them freely without affecting the original input or other callers.
4949
50+
Exception: when ``had_language_extensions`` is False, both fields
51+
alias the caller's input dict (no copy overhead). Callers that need
52+
to mutate should ``copy.deepcopy()`` first in that case.
53+
5054
Attributes
5155
----------
5256
expanded_template : Dict[str, Any]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"AWSTemplateFormatVersion": "2010-09-09",
3+
"Transform": "AWS::LanguageExtensions",
4+
"Mappings": {
5+
"A": {
6+
"B": {
7+
"C": "D"
8+
}
9+
}
10+
},
11+
"Conditions": {
12+
"TrueCondition": {
13+
"Fn::Equals": [
14+
"false",
15+
"true"
16+
]
17+
}
18+
},
19+
"Resources": {
20+
"MyTopic": {
21+
"Condition": "TrueCondition",
22+
"Type": "AWS::SNS::Topic",
23+
"Properties": {
24+
"TopicName": {
25+
"Fn::FindInMap": [
26+
"A",
27+
"Undefined",
28+
"C"
29+
]
30+
}
31+
}
32+
}
33+
}
34+
}

tests/unit/lib/cfn_language_extensions/compatibility/test_kotlin_compatibility.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ def test_foreach_conditions(test_name: str, input_path: Path, expected_path: Pat
192192
"fnFindInMapWithUnsupportedFunctionFnGetAtt",
193193
"fnFindInMapWithUnsupportedFunctionFnRef",
194194
"fnFindInMapWithUnsupportedFunctionInMapName",
195-
"templateFnInMapInWhenFalseConditionInResourceWithInvalidStringPath",
196195
]
197196

198197
# Templates that should error but have compatibility issues
@@ -311,6 +310,9 @@ def test_error_templates_with_placeholder(template_name: str):
311310
"toJsonStringWithSimpleTags",
312311
"toJsonStringWithSplitThatResolves",
313312
"toJsonStringWithStackNamePseudoParam",
313+
# False-condition resources: CloudFormation skips validation, so invalid
314+
# FindInMap keys are preserved rather than erroring.
315+
"templateFnInMapInWhenFalseConditionInResourceWithInvalidStringPath",
314316
]
315317

316318
# Templates with known compatibility issues

0 commit comments

Comments
 (0)