Skip to content

fix: preserve Fn::FindInMap with unresolved Ref keys in PARTIAL mode#9006

Open
polyomino24 wants to merge 1 commit into
aws:developfrom
polyomino24:fix/issue-9004-findinmap-partial-resolution
Open

fix: preserve Fn::FindInMap with unresolved Ref keys in PARTIAL mode#9006
polyomino24 wants to merge 1 commit into
aws:developfrom
polyomino24:fix/issue-9004-findinmap-partial-resolution

Conversation

@polyomino24
Copy link
Copy Markdown

@polyomino24 polyomino24 commented May 14, 2026

Which issue(s) does this change fix?

#9004

Why is this change necessary?

sam build (1.160.0) fails with Fn::FindInMap layout is incorrect for any AWS::LanguageExtensions template that uses Fn::FindInMap with a !Ref Param as one of the keys, when no value is supplied for that parameter at build time (no --parameter-overrides, no Default). The same template built successfully with 1.159.1 — this is a regression introduced together with the new cfn_language_extensions module.

Root cause: FnRefResolver correctly preserves an unresolved {"Ref": "ENV"} dict in ResolutionMode.PARTIAL (the default for SAM CLI integration), but FnFindInMapResolver then validated the resolved keys with isinstance(..., str) and raised InvalidTemplateException unconditionally, regardless of resolution mode.

How does it address the issue?

In samcli/lib/cfn_language_extensions/resolvers/fn_find_in_map.py, mirror the FnRefResolver PARTIAL-mode pattern: when any resolved FindInMap key arrives as a dict (an unresolved nested intrinsic) and resolution_mode == PARTIAL, return the original Fn::FindInMap expression so CloudFormation can resolve it at deploy time. Non-dict, non-str keys (e.g. an int literal) remain a layout error in either mode, preserving existing behavior for genuine template mistakes.

What side effects does this change have?

  • 3 Kotlin-compatibility tests in test_kotlin_compatibility.py previously asserted that Fn::FindInMap with Ref/GetAtt to a resource raises in default (PARTIAL) mode. That assertion captured the Kotlin reference's strict semantics, which conflict with SAM CLI's documented PARTIAL intent ("preserve unresolvable references in the output"). Those templates were moved to a new ERROR_TEMPLATES_FULL_MODE_ONLY list and are now asserted under ResolutionMode.FULL, keeping Kotlin parity for the strict callers while letting PARTIAL mode pass the expression through to CloudFormation. The remaining fnFindInMapWithUnsupportedFunctionFnSub template is unaffected (it already errored via a different code path).
  • No public API changes. No changes to FULL mode behavior.

Mandatory Checklist

PRs will only be reviewed after checklist is complete

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

FnFindInMapResolver was unconditionally raising "Fn::FindInMap layout
is incorrect" when a key arrived as an unresolved {"Ref": ...} dict in
PARTIAL mode, breaking `sam build` for any AWS::LanguageExtensions
template using !Ref to a parameter as a FindInMap key when no value
was supplied. Mirror FnRefResolver's pattern: preserve the expression
in PARTIAL mode and let CloudFormation resolve at deploy time. Real
layout errors (non-dict, non-string keys) still raise.

Fixes aws#9004
@polyomino24 polyomino24 requested a review from a team as a code owner May 14, 2026 09:56
@github-actions github-actions Bot added pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. labels May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant