aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.47k stars 1.16k forks source link

Bug: sam local start-api - TypeError #6036

Closed aguerere-fa closed 8 months ago

aguerere-fa commented 9 months ago

Description:

Trying to run SAM project (Lambda function) locally on M2 Mac in MacOS Sonoma 14.0 throws error: An unexpected error was encountered while executing "sam local start-api"

Steps to reproduce:

sam local start-api

Observed result:

2023-10-04 12:11:47,637 | Config file location: /Users/beto/Work/AnonymousProxyApi/samconfig.toml
2023-10-04 12:11:47,640 | Loading configuration values from [default.['local', 'start-api'].parameters] (env.command_name.section) in config file at
'/Users/beto/Work/AnonymousProxyApi/samconfig.toml'...
2023-10-04 12:11:47,641 | Configuration values successfully loaded.
2023-10-04 12:11:47,641 | Configuration values are: {}
2023-10-04 12:11:47,660 | Using SAM Template at /Users/beto/Work/AnonymousProxyApi/.aws-sam/build/template.yaml
2023-10-04 12:11:47,703 | Using config file: samconfig.toml, config environment: default
2023-10-04 12:11:47,704 | Expand command line arguments to:
2023-10-04 12:11:47,705 | --template_file=/Users/beto/Work/AnonymousProxyApi/.aws-sam/build/template.yaml --host=127.0.0.1 --port=3000 --static_dir=public
--layer_cache_basedir=/Users/beto/.aws-sam/layers-pkg --container_host=localhost --container_host_interface=127.0.0.1
2023-10-04 12:11:47,768 | local start-api command is called
2023-10-04 12:11:47,788 | Collected default values for parameters: {}
2023-10-04 12:11:47,808 | Sam customer defined id is more priority than other IDs. Customer defined id for resource SharedDependencyLayer is SharedDependencyLayer
2023-10-04 12:11:47,809 | There is no customer defined id or cdk path defined for resource ApiDomainCert, so we will use the resource logical id as the resource id 2023-10-04 12:11:47,810 | There is no customer defined id or cdk path defined for resource HttpApiGW, so we will use the resource logical id as the resource id
2023-10-04 12:11:47,811 | Sam customer defined id is more priority than other IDs. Customer defined id for resource GetAnonymousSmsSendPageUrl is
GetAnonymousSmsSendPageUrl
2023-10-04 12:11:47,812 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,814 | Unable to resolve property HostedZoneId: OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ZoneId'])]).
Leaving as is.
2023-10-04 12:11:47,815 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,816 | Unable to resolve property issuer: OrderedDict([('Fn::ImportValue', OrderedDict([('Fn::Sub', '${CognitoStack}-ProviderURL')]))]). Leaving as is.
2023-10-04 12:11:47,817 | Unable to resolve property audience: [OrderedDict([('Fn::FindInMap', ['Cognito', OrderedDict([('Ref', 'Env')]), 'ClientId'])])]. Leaving
as is.
2023-10-04 12:11:47,818 | Unable to resolve property AllowOrigins: ['http://localhost:4200', OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref',
'Env')]), 'webUrl'])])]. Leaving as is.
2023-10-04 12:11:47,819 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,820 | Unable to resolve property HostedZoneId: OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ZoneId'])]).
Leaving as is.
2023-10-04 12:11:47,821 | 0 stacks found in the template
2023-10-04 12:11:47,822 | Collected default values for parameters: {}
2023-10-04 12:11:47,836 | Sam customer defined id is more priority than other IDs. Customer defined id for resource SharedDependencyLayer is SharedDependencyLayer
2023-10-04 12:11:47,837 | There is no customer defined id or cdk path defined for resource ApiDomainCert, so we will use the resource logical id as the resource id 2023-10-04 12:11:47,838 | There is no customer defined id or cdk path defined for resource HttpApiGW, so we will use the resource logical id as the resource id
2023-10-04 12:11:47,838 | Sam customer defined id is more priority than other IDs. Customer defined id for resource GetAnonymousSmsSendPageUrl is
GetAnonymousSmsSendPageUrl
2023-10-04 12:11:47,840 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,841 | Unable to resolve property HostedZoneId: OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ZoneId'])]).
Leaving as is.
2023-10-04 12:11:47,842 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,844 | Unable to resolve property issuer: OrderedDict([('Fn::ImportValue', OrderedDict([('Fn::Sub', '${CognitoStack}-ProviderURL')]))]). Leaving as is.
2023-10-04 12:11:47,845 | Unable to resolve property audience: [OrderedDict([('Fn::FindInMap', ['Cognito', OrderedDict([('Ref', 'Env')]), 'ClientId'])])]. Leaving
as is.
2023-10-04 12:11:47,845 | Unable to resolve property AllowOrigins: ['http://localhost:4200', OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref',
'Env')]), 'webUrl'])])]. Leaving as is.
2023-10-04 12:11:47,846 | Unable to resolve property DomainName: OrderedDict([('Fn::If', ['isLocalDev', OrderedDict([('Fn::Sub',
'aff-api-${Application}.aws-opg-dev01.truesource.com')]), OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ApiName'])])])]). Leaving as is.
2023-10-04 12:11:47,848 | Unable to resolve property HostedZoneId: OrderedDict([('Fn::FindInMap', ['DomainName', OrderedDict([('Ref', 'Env')]), 'ZoneId'])]).
Leaving as is.
2023-10-04 12:11:47,849 | 4 resources found in the stack
2023-10-04 12:11:47,849 | Found Serverless function with name='GetAnonymousSmsSendPageUrl' and CodeUri='GetAnonymousSmsSendPageUrl'
2023-10-04 12:11:47,850 | --base-dir is not presented, adjusting uri GetAnonymousSmsSendPageUrl relative to
/Users/beto/Work/AnonymousProxyApi/.aws-sam/build/template.yaml
2023-10-04 12:11:47,865 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2023-10-04 12:11:47,907 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2023-10-04 12:11:47,908 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId': '606dcd86-d33d-4a1a-8a72-ad2bb9cdda6f', 'installationId':
'648b7d25-cbbf-4c58-a723-156e3fe2c8f6', 'sessionId': '6d1f6257-0ed2-46f8-b2e5-8029b0237ce9', 'executionEnvironment': 'CLI', 'ci': False, 'pyversion': '3.8.13',
'samcliVersion': '1.94.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam local start-api', 'metricSpecificAttributes':
{'projectType': 'CFN', 'gitOrigin': None, 'projectName': '2f90e118d9accf5f71544d3ff1f0145bdd59f66a366972603d1b573ba1410b26', 'initialCommit': None}, 'duration':
161, 'exitReason': 'TypeError', 'exitCode': 255}}]}
2023-10-04 12:11:47,909 | Unable to find Click Context for getting session_id.
2023-10-04 12:11:47,913 | Sending Telemetry: {'metrics': [{'events': {'requestId': '99b1b80b-e2ea-48de-af37-98d25eabb687', 'installationId':
'648b7d25-cbbf-4c58-a723-156e3fe2c8f6', 'sessionId': '6d1f6257-0ed2-46f8-b2e5-8029b0237ce9', 'executionEnvironment': 'CLI', 'ci': False, 'pyversion': '3.8.13',
'samcliVersion': '1.94.0', 'metricSpecificAttributes': {'events': [{'event_name': 'SamConfigFileExtension', 'event_value': '.toml', 'thread_id':
'7b4f4fa5eed040d582c2defe42f940a3', 'time_stamp': '2023-10-04 16:11:47.637', 'exception_name': None}]}}}]}
2023-10-04 12:11:48,514 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
2023-10-04 12:11:48,517 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)

Error: sequence item 1: expected str instance, collections.OrderedDict found Traceback: File "click/core.py", line 1055, in main File "click/core.py", line 1657, in invoke File "click/core.py", line 1657, in invoke File "click/core.py", line 1404, in invoke File "click/core.py", line 760, in invoke File "click/decorators.py", line 84, in new_func File "click/core.py", line 760, in invoke File "samcli/lib/telemetry/metric.py", line 184, in wrapped File "samcli/lib/telemetry/metric.py", line 149, in wrapped File "samcli/lib/utils/version_checker.py", line 42, in wrapped File "samcli/cli/main.py", line 95, in wrapper File "samcli/commands/local/start_api/cli.py", line 118, in cli File "samcli/commands/local/start_api/cli.py", line 224, in do_cli File "samcli/commands/local/lib/local_api_service.py", line 37, in init File "samcli/lib/providers/api_provider.py", line 37, in init File "samcli/lib/providers/api_provider.py", line 64, in _extract_api File "samcli/lib/providers/sam_api_provider.py", line 74, in extract_resources File "samcli/lib/providers/sam_api_provider.py", line 326, in _extract_from_serverless_http File "samcli/lib/providers/cfn_base_api_provider.py", line 245, in extract_cors_http

An unexpected error was encountered while executing "sam local start-api". Search for an existing issue: https://github.com/aws/aws-sam-cli/issues?q=is%3Aissue+is%3Aopen+Bug%3A%20sam%20local%20start-api%20-%20TypeError Or create a bug report: https://github.com/aws/aws-sam-cli/issues/new?template=Bug_report.md&title=Bug%3A%20sam%20local%20start-api%20-%20TypeError

Expected result:

SAM runs Lambda function locally with no errors

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: MacOS Sonoma 14.0
  2. sam --version: SAM CLI, version 1.94.0
  3. AWS region: us-east-1
{
  "version": "1.94.0",
  "system": {
    "python": "3.8.13",
    "os": "macOS-14.0-arm64-arm-64bit"
  },
  "additional_dependencies": {
    "docker_engine": "24.0.6",
    "aws_cdk": "Not available",
    "terraform": "Not available"
  },
  "available_beta_feature_env_vars": [
    "SAM_CLI_BETA_FEATURES",
    "SAM_CLI_BETA_BUILD_PERFORMANCE",
    "SAM_CLI_BETA_TERRAFORM_SUPPORT",
    "SAM_CLI_BETA_RUST_CARGO_LAMBDA"
  ]
}
sriram-mv commented 9 months ago

Thanks for raising an issue! Would you be able to share a snippet of the template itself? That will help us triage the root cause of this issue.

aguerere-fa commented 9 months ago

@sriram-mv here is a snippet of the template with replaced important values from our environments.

AWSTemplateFormatVersion: "2010-09-09"
Transform: 
  - AWS::Serverless-2016-10-31
  - Name: DatadogServerless
    Parameters:
      stackName: !Ref "AWS::StackName"
      apiKey: "xxxxxxx"
      nodeLayerVersion: 88 
      extensionLayerVersion: 41
      service: "XXXX API" # Optional
      env: !Ref Env # Optional
      tags: "App:Xxxxx,Stack:XXXX," # Optional
      # For additional parameters, see the Configuration section

Description: Template for deploying API Gateway backed by lambda

Parameters:
  Application:
    Type: String
    Description: Name of the application
  Env:
    Type: String 
    AllowedValues:
      - "Local"
      - "Dev"
      - "SIT"
      - "QA"
      - "Prod"
    Description: "The Environment tag/naming pre/post-pend"
  CognitoStack: 
    Type: String
    Description: Enter the name of the cognito user pool pipeline stack

Conditions:
  isLocalDev: !Equals 
    - !Ref Env
    - Local

Mappings:
  DomainName:
    Local: 
      ApiName: xxxxxx-api-anon.aws-opg-dev01.xxxxx.com
      webUrl: https://xxxxxx.aws-opg-dev01.xxxxx.com
      Zone: aws-opg-dev01.xxxxx.com.
      ZoneId: XXXXX
    Dev:
      ApiName: xxxxxx-api-anon.aws-opg-dev01.xxxxx.com
      webUrl: https://xxxxxx.aws-opg-dev01.xxxxx.com
      Zone: aws-opg-dev01.xxxxx.com.
      ZoneId: XXXXX
    SIT:
      ApiName: xxxxxx-api-anon.aws-opg-sit.xxxxx.com
      webUrl: https://xxxxxx.aws-opg-sit.xxxxx.com
      Zone: aws-opg-sit.xxxxx.com.
      ZoneId: XXXX
    QA:
      ApiName: xxxxxx-api-anon.aws-opg-qa01.xxxxx.com
      webUrl: https://xxxxxx.aws-opg-qa01.xxxxx.com
      Zone: aws-opg-qa01.xxxxx.com.
      ZoneId: XXXX
    Prod:
      ApiName: xxxxxx-api-anon.xxxx.com
      webUrl: https://xxxxxx.xxxx.com
      Zone: xxx.com.
      ZoneId: XXXXXXXX
  Cognito:
    Local: 
      ClientId: 'xxxx'
      Secret: 'xxxx'
    Dev:
      ClientId: 'xxxx'
      Secret: 'xxxx'
    SIT: 
      ClientId: 'xxxxx'
      Secret: 'xxxx'
    QA:
      ClientId: 'xxxx'
      Secret: 'xxxx'
    Prod:
      ClientId: 'xxxx'
      Secret: 'xxxx'

Resources:
  SharedDependencyLayer: 
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: !Sub "${Application}-shared-dependency-layer-${Env}"
      CompatibleRuntimes: 
        - nodejs18.x
      ContentUri: src/dependencies/shared/nodejs/
    Metadata:
      BuildMethod: nodejs18.x

  ApiDomainCert:
    Type: 'AWS::CertificateManager::Certificate'
    Properties:
      DomainName: !If 
        - isLocalDev
        - !Sub aff-api-${Application}.aws-opg-dev01.xxxxx.com
        - !FindInMap [DomainName, !Ref Env, ApiName]
      ValidationMethod: DNS 
      DomainValidationOptions:
        - 
          HostedZoneId: !FindInMap [DomainName, !Ref Env, ZoneId]
          DomainName: !If 
            - isLocalDev
            - !Sub aff-api-${Application}.aws-opg-dev01.xxxxxx.com
            - !FindInMap [DomainName, !Ref Env, ApiName]

  HttpApiGW:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: !Ref Env
      Auth:
        Authorizers:
          OAuth2Authorizer:
            JwtConfiguration:
              issuer:
                Fn::ImportValue: 
                  Fn::Sub: "${CognitoStack}-ProviderURL"
              audience:
                - !FindInMap [Cognito, !Ref Env, ClientId]
            IdentitySource: $request.header.Authorization
        DefaultAuthorizer: OAuth2Authorizer
      CorsConfiguration: 
        AllowOrigins:
          - "http://localhost:4200"
          - !FindInMap [DomainName, !Ref Env, webUrl] 
        AllowHeaders:
          - authorization
          - content-type
          - version
          - client
        AllowMethods:
          - "*"
        MaxAge: 600
        AllowCredentials: true
      Domain: 
        CertificateArn: !Ref ApiDomainCert
        DomainName: !If 
          - isLocalDev
          - !Sub aff-api-${Application}.aws-opg-dev01.xxxx.com
          - !FindInMap [DomainName, !Ref Env, ApiName]
        Route53: 
          HostedZoneId: !FindInMap [DomainName, !Ref Env, ZoneId]   
        SecurityPolicy: TLS_1_2

  GetAnonymousSmsSendPageUrl:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName:
        !Sub '${Application}-get-anonymous-sms-send-page-url-${Env}'
      Handler: get-anonymous-sms-send-page-url.handler
      CodeUri: src/handlers/AnonymousSmsSendPageUrl/get-anonymous-sms-send-page-url/
      Runtime: nodejs18.x
      Timeout: 60
      MemorySize: 1024
      Layers: 
        - !Ref SharedDependencyLayer
      Events:
        ApiCall:
          Type: HttpApi
          Properties:
            ApiId: !Ref HttpApiGW
            Path: /AnonymousSmsSendPageUrl/{WorkOrderId}/{AffiliateId}
            Method: GET
        ApiCall2:
          Type: HttpApi
          Properties:
            ApiId: !Ref HttpApiGW
            Path: /anonymousSmsSendPageUrl/{WorkOrderId}/{AffiliateId}
            Method: GET

Outputs:
  WebEndpoint:
    Description: "API Gateway endpoint URL"
    Value: !Sub "https://${HttpApiGW.DomainName}"
aguerere-fa commented 9 months ago

For what it's worth, doing sam sync worked fine under the same template.

moelasmar commented 8 months ago

This issue raised while parsing the CORS configuration of the API HttpApiGW. SAM CLI expects the CORS AllowOrigin property to be a list of strings, but it received a dict because the FindInMap intrinsic function does not processed because it depends on the stack parameter Env which it does not has a default value in the template and also you did not provide it in the command.

You can solve this problem by running the sam local command as following: sam local start-api --debug --parameter-overrides Env=Local Application=test CognitoStack=stack

moelasmar commented 8 months ago

I will close this issue as resolved, please raise a new issue if you faced any other problems.

github-actions[bot] commented 8 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

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.