Repository navigation
Bug: sam build fails with "Fn::FindInMap layout is incorrect" when using AWS::LanguageExtensions with an unresolved !Ref parameter as a map key (regression in 1.160.0) #9004
Description
Description:
sam build fails with Fn::FindInMap layout is incorrect when a template uses AWS::LanguageExtensions with Fn::FindInMap where a template parameter is used as a map key via !Ref, and no value is supplied for that parameter at build time (i.e., without --parameter-overrides and no Default defined).
This seems to be a regression introduced in 1.160.0 — the same template built successfully with 1.159.1.
Steps to reproduce:
- Create a new directory and add the following files:
samconfig.yaml
version: 0.1
stg:
global:
parameters:
parameter_overrides:
- ENV=stgtemplate.yaml
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::LanguageExtensions
Parameters:
ENV:
Type: String
AllowedValues: [stg, prod]
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: index.handler
Runtime: nodejs22.x
Role: !FindInMap [EnvConfig, !Ref ENV, IAM]
Mappings:
EnvConfig:
stg:
IAM: arn:aws:iam::123456789012:role/lambda-role-stg
prod:
IAM: arn:aws:iam::123456789012:role/lambda-role-prodindex.js
export const handler = async (_event, _context) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Hello World',
}),
}
}- Run
sam buildin that directory with AWS SAM CLI v1.160.0
Observed result:
Show output
% sam build --debug
2026-05-14 15:42:16,844 | Config file location:
/Users/ta.ishikawa/sam-cli-bug/samconfig.yaml
2026-05-14 15:42:16,849 | Loading configuration values from [default.['build'].parameters]
(env.command_name.section) in config file at
'/Users/ta.ishikawa/sam-cli-bug/samconfig.yaml'...
2026-05-14 15:42:16,849 | Configuration values successfully loaded.
2026-05-14 15:42:16,850 | Configuration values are: {}
2026-05-14 15:42:16,851 | Using SAM Template at
/Users/ta.ishikawa/sam-cli-bug/template.yaml
2026-05-14 15:42:16,852 | Empty parameter set ({})
2026-05-14 15:42:16,876 | OSError occurred while reading TOML file: [Errno 2] No such file
or directory: '/Users/ta.ishikawa/sam-cli-bug/samconfig.toml'
2026-05-14 15:42:16,877 | Using config file: samconfig.toml, config environment: default
2026-05-14 15:42:16,878 | Expand command line arguments to:
2026-05-14 15:42:16,878 | --template_file=/Users/ta.ishikawa/sam-cli-bug/template.yaml
--mount_with=READ --build_dir=.aws-sam/build --cache_dir=.aws-sam/cache
2026-05-14 15:42:16,941 | 'build' command is called
2026-05-14 15:42:16,942 | Expanding CloudFormation Language Extensions (Phase 1)
2026-05-14 15:42:16,943 | Processing Fn::ForEach constructs in template
2026-05-14 15:42:16,943 | Resolving intrinsic functions in template
2026-05-14 15:42:16,944 | Failed to expand CloudFormation Language Extensions:
Fn::FindInMap layout is incorrect
2026-05-14 15:42:16,944 | Telemetry endpoint configured to be
https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2026-05-14 15:42:17,004 | No container socket path in global storage, falling back to
DOCKER_HOST detection:
2026-05-14 15:42:17,005 | Telemetry endpoint configured to be
https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2026-05-14 15:42:17,005 | Unable to find Click Context for getting session_id.
2026-05-14 15:42:17,006 | No container socket path in global storage, falling back to
DOCKER_HOST detection:
2026-05-14 15:42:17,007 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId':
'b6466981-55a4-44ed-87e5-d630d5d362cd', 'installationId':
'0fe4a75f-9858-4a11-99c0-5e7442a73e66', 'sessionId':
'8baa53f2-54da-4d69-8f30-5c2f7c9fa5e7', 'executionEnvironment': 'CLI', 'ci': False,
'pyversion': '3.13.11', 'samcliVersion': '1.160.0', 'osPlatform': 'Darwin',
'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam
build', 'metricSpecificAttributes': {'projectType': 'CFN', 'gitOrigin': None,
'projectName': 'f9fbd5b7efdc83a3be25efdc23b036d1a8f30b42b0cd3d93878fb16d5ccb80a3',
'initialCommit': None, 'containerEngine': 'docker-default', 'adminContainerPreference':
None}, 'duration': 66, 'exitReason': 'InvalidSamDocumentException', 'exitCode': 255}}]}
2026-05-14 15:42:17,007 | Sending Telemetry: {'metrics': [{'events': {'requestId':
'cb03bbbc-7750-4173-bc4b-cd575edc9164', 'installationId':
'0fe4a75f-9858-4a11-99c0-5e7442a73e66', 'sessionId':
'8baa53f2-54da-4d69-8f30-5c2f7c9fa5e7', 'executionEnvironment': 'CLI', 'ci': False,
'pyversion': '3.13.11', 'samcliVersion': '1.160.0', 'osPlatform': 'Darwin', 'commandName':
'sam build', 'metricSpecificAttributes': {'events': [{'event_name':
'SamConfigFileExtension', 'event_value': '.yaml', 'thread_id':
'7b770acae30e4e35af06873f64ecae54', 'time_stamp': '2026-05-14 06:42:16.844088+00',
'exception_name': None}, {'event_name': 'SamConfigFileExtension', 'event_value': '.toml',
'thread_id': '2d863e0b995e4373b77a3a70a49b2d68', 'time_stamp': '2026-05-14
06:42:16.877624+00', 'exception_name': None}], 'containerEngine': 'docker-default'}}}]}
2026-05-14 15:42:17,433 |
HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com',
port=443): Read timed out. (read timeout=0.1)
2026-05-14 15:42:17,435 |
HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com',
port=443): Read timed out. (read timeout=0.1)
Error: Fn::FindInMap layout is incorrect
Traceback:
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/core.py", line 1082, in main
rv = self.invoke(ctx)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/core.py", line 1697, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/core.py", line 1443, in invoke
return ctx.invoke(self.callback, **ctx.params)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/core.py", line 788, in invoke
return __callback(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/cli/cli_config_file.py", line 366, in wrapper
return func(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/decorators.py", line 92, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/click/core.py", line 788, in invoke
return __callback(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/lib/telemetry/metric.py", line 190, in wrapped
raise exception # pylint: disable=raising-bad-type
^^^^^^^^^^^^^^^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/lib/telemetry/metric.py", line 155, in wrapped
return_value = func(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/lib/utils/version_checker.py", line 43, in wrapped
actual_result = func(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/cli/main.py", line 95, in wrapper
return func(*args, **kwargs)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/commands/build/command.py", line 175, in cli
do_cli(
~~~~~~^
ctx,
^^^^
...<22 lines>...
use_buildkit,
^^^^^^^^^^^^^
) # pragma: no cover
^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/commands/build/command.py", line 244, in do_cli
with BuildContext(
~~~~~~~~~~~~^
function_identifier,
^^^^^^^^^^^^^^^^^^^^
...<22 lines>...
use_buildkit=use_buildkit,
^^^^^^^^^^^^^^^^^^^^^^^^^^
) as ctx:
^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/commands/build/build_context.py", line 202, in __enter__
self.set_up()
~~~~~~~~~~~^^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/commands/build/build_context.py", line 208, in set_up
self._stacks, remote_stack_full_paths = SamLocalStackProvider.get_stacks(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
self._template_file,
^^^^^^^^^^^^^^^^^^^^
parameter_overrides=self._parameter_overrides,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
global_parameter_overrides=self._global_parameter_overrides,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/lib/providers/sam_stack_provider.py", line 274, in get_stacks
lang_ext_result = expand_language_extensions(template_dict, parameter_values=parameter_values)
File "/Users/ta.ishikawa/.pyenv/versions/3.13.11/lib/python3.13/site-packages/samcli/lib/cfn_language_extensions/sam_integration.py", line 555, in expand_language_extensions
raise InvalidSamDocumentException(str(e)) from e
An unexpected error was encountered while executing "sam build".
Search for an existing issue:
https://github.com/aws/aws-sam-cli/issues?q=is%3Aissue+is%3Aopen+Bug%3A%20sam%20build%20-%20InvalidSamDocumentException
Or create a bug report:
https://github.com/aws/aws-sam-cli/issues/new?template=Bug_report.md&title=Bug%3A%20sam%20build%20-%20InvalidSamDocumentException
Expected result:
Build succeeds. sam build does not require --parameter-overrides — it should process the template in partial resolution mode, preserving Fn::FindInMap expressions whose keys cannot be resolved locally, and let CloudFormation resolve them at deploy time.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
- OS: Mac
sam --version: SAM CLI, version 1.160.0- AWS region: ap-northeast-1
# Paste the output of `sam --info` here
{
"version": "1.160.0",
"system": {
"python": "3.13.11",
"os": "macOS-15.7.2-arm64-arm-64bit-Mach-O"
},
"additional_dependencies": {
"container_engine": "Docker(v29.3.1)",
"aws_cdk": "Not available",
"terraform": "1.14.8"
},
"available_beta_feature_env_vars": [
"SAM_CLI_BETA_FEATURES",
"SAM_CLI_BETA_BUILD_PERFORMANCE",
"SAM_CLI_BETA_TERRAFORM_SUPPORT",
"SAM_CLI_BETA_PACKAGE_PERFORMANCE",
"SAM_CLI_BETA_UV_PACKAGE_MANAGER"
]
}
Root cause analysis:
The bug is in samcli/lib/cfn_language_extensions/resolvers/fn_find_in_map.py.
When sam build is invoked without --parameter-overrides, the ENV parameter has no value in context.parameter_values and no Default in the template. FnRefResolver correctly returns {"Ref": "ENV"} (the unresolved dict) in PARTIAL mode. However, FnFindInMapResolver then validates the resolved key with isinstance(top_key, str) and unconditionally raises InvalidTemplateException regardless of resolution mode:
aws-sam-cli/samcli/lib/cfn_language_extensions/resolvers/fn_find_in_map.py
Lines 98 to 104 in c406852
| # Validate resolved keys are strings | |
| if not isinstance(map_name, str): | |
| raise InvalidTemplateException("Fn::FindInMap layout is incorrect") | |
| if not isinstance(top_key, str): | |
| raise InvalidTemplateException("Fn::FindInMap layout is incorrect") | |
| if not isinstance(second_key, str): | |
| raise InvalidTemplateException("Fn::FindInMap layout is incorrect") |
This is inconsistent with FnRefResolver, which correctly handles the partial mode case:
aws-sam-cli/samcli/lib/cfn_language_extensions/resolvers/fn_ref.py
Lines 83 to 86 in c406852
| if self.context.resolution_mode == ResolutionMode.FULL: | |
| raise UnresolvableReferenceError("Ref", ref_target) | |
| # In partial mode, preserve the reference | |
| return {"Ref": ref_target} |
Notably, ResolutionMode.PARTIAL is the documented default for SAM CLI integration (models.py: "Use this mode for SAM integration where resource references cannot be resolved locally"), and process_template_for_sam_cli explicitly sets resolution_mode=ResolutionMode.PARTIAL. The cfn_language_extensions module did not exist in 1.159.1, so this is a new regression (likely introduced by #8637).
Proposed Fix
In fn_find_in_map.py, mirror the FnRefResolver pattern — preserve the original Fn::FindInMap expression when in PARTIAL mode and a key cannot be resolved to a string:
# fn_find_in_map.py (proposed fix)
if not isinstance(map_name, str) or not isinstance(top_key, str) or not isinstance(second_key, str):
from samcli.lib.cfn_language_extensions.models import ResolutionMode
if self.context.resolution_mode == ResolutionMode.PARTIAL:
return value # preserve as-is; CloudFormation will resolve at deploy time
raise InvalidTemplateException("Fn::FindInMap layout is incorrect")Additional notes
sam validatepasses on the same template (different code path, not affected by this bug)- Workaround: use
sam build --config-env stgsoENV=stgis passed as a parameter override — but this breaks the common workflow of building once for all environments
Activity
roger-zhangg commentedon May 14, 2026
Thanks for reporting, we are taking a look now. In the meantime, you can downgrade to (https://github.com/aws/aws-sam-cli/releases/tag/v1.159.1) to unblock.
bnusunny commentedon May 14, 2026
There tranform ordering is important. please move the
AWS::LanguageExtensionsbeforeAWS::Serverless-2016-10-31.bnusunny commentedon May 14, 2026
I can reproduce this issue and working on a fix.
jkaraganis-bch commentedon May 14, 2026
Another workaround that worked for us and might be helpful for others:
We were only including LanguageExtensions due to using Fn::ToJsonString for one parameter. We were able to replace that with a !Sub, remove LanguageExtensions from the Transform section and get our build working again.
fix: preserve Fn::FindInMap with unresolved param Ref keys in PARTIAL…
test: end-to-end regression test for issue #9004
bnusunny commentedon May 15, 2026
Fixed in #9010
https://github.com/aws/aws-sam-cli/releases/tag/v1.160.1
github-actions commentedon May 15, 2026
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
fix(cfn-lang-ext): preserve template-time intrinsics with unresolved …
docs(designs): reframe motivation around review-surface for output shape