Function with 'Fn::Transform' as first events causes 'sam local start-api' to crash
- Dominant language
- Python
- Stars
- 6.7k
- Forks
- 1.2k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 52
Description
**Description:**
If a template contains a Function, of which the top-most event is a `Fn::Transform` entry. Then `sam local start-api` fails to start with something like:
```
...
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/sam_api_provider.py", line 191, in extract_routes_from_events
for _, event in serverless_function_events.items():
AttributeError: 'str' object has no attribute 'items'
```
This template does not cause any issues with other commands, including `sam local invoke`, `sam package` and `sam deploy`.
**Steps to reproduce the issue:**
1. Given the template:
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
Func1:
Type: AWS::Serverless::Function
Properties:
CodeUri: "./"
Handler: "main"
Runtime: "go1.x"
Events:
Api1:
Type: Api
Properties:
Path: "/func1"
Method: "GET"
Func2:
Type: AWS::Serverless::Function
Properties:
CodeUri: "./"
Handler: "main"
Runtime: "go1.x"
Events:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: "events.yaml"
```
2. Run `sam local start-api`
**Observed result:**
`sam local start-api` fails to start:
```
Traceback (most recent call last):
File "/usr/local/bin/sam", line 11, in
load_entry_point('aws-sam-cli==0.21.0', 'console_scripts', 'sam')()
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/lib/telemetry/metrics.py", line 94, in wrapped
raise exception # pylint: disable=raising-bad-type
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/lib/telemetry/metrics.py", line 65, in wrapped
return_value = func(*args, **kwargs)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/start_api/cli.py", line 60, in cli
parameter_overrides) # pragma: no cover
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/start_api/cli.py", line 95, in do_cli
static_dir=static_dir)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/local_api_service.py", line 43, in __init__
cwd=self.cwd)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/api_provider.py", line 42, in __init__
self.api = self._extract_api(self.resources)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/api_provider.py", line 71, in _extract_api
provider.extract_resources(resources, collector, cwd=self.cwd)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/sam_api_provider.py", line 52, in extract_resources
self._extract_routes_from_function(logical_id, resource, collector)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/sam_api_provider.py", line 172, in _extract_routes_from_function
self.extract_routes_from_events(logical_id, serverless_function_events, collector)
File "/usr/local/Cellar/aws-sam-cli/0.21.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/sam_api_provider.py", line 191, in extract_routes_from_events
for _, event in serverless_function_events.items():
AttributeError: 'str' object has no attribute 'items'
```
**Expected result:**
`sam local start-api` should process the `Fn::Transform` entry and run properly.
_Or_ (also acceptable for my use case) `sam local start-api` should ignore the `Fn::Transform` entry completely and not crash.
**Workarounds:**
If you add any other event above the `Fn::Transform` entry, `sam local start-api` will work.
But the included events (`events.yaml` in this case) do not get picked up by `sam local start-api`.
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
Func1:
Type: AWS::Serverless::Function
Properties:
CodeUri: "./"
Handler: "main"
Runtime: "go1.x"
Events:
Api1:
Type: Api
Properties:
Path: "/func1"
Method: "GET"
Func2:
Type: AWS::Serverless::Function
Properties:
CodeUri: "./"
Handler: "main"
Runtime: "go1.x"
Events:
Schedule2:
Type: Schedule
Properties:
Schedule: "rate(5 minutes)"
Fn::Transform:
Name: AWS::Include
Parameters:
Location: "events.yaml"
```
**Versions:**
```
SAM CLI, version 0.21.0
aws-cli/1.16.210 Python/3.7.4 Darwin/18.7.0 botocore/1.12.200
```
Contributor guide
Assessment
This issue has not been assessed yet.