Skip to content

Bug: Duplicate method 'OPTIONS' error #3816

@royassis

Description

@royassis

SAM CLI, version 1.139.0
Linux

When there are both POST and PUT, api events in AWS::Serverless::Function resource +
Cors section in an AWS::Serverless::Api resource.

I get an error:

Resource handler returned message: "Errors found during import:
Duplicate method 'OPTIONS' on resource at path '/datasets'
(Service: ApiGateway, Status Code: 400, Request ID:
xxx) (SDK Attempt Count: 1)"
(RequestToken: xxx,
HandlerErrorCode: InvalidRequest)

This is the template file :

AWSTemplateFormatVersion: '2010-09-09'
Transform:
  - AWS::Serverless-2016-10-31
  - AWS::LanguageExtensions

Globals:
  Function:
    Timeout: 60
    MemorySize: 512
    Tracing: Active
    Tags:
      GitRev: !Ref GitRev
    Environment:
      Variables:
        DbName: !Ref DbName
        MongoSecretName: !Ref MongoSecretName
        StackName: !Sub ${AWS::StackName}
        POWERTOOLS_SERVICE_NAME: !Sub ${AWS::StackName}
        POWERTOOLS_LOG_LEVEL: INFO
        Environment: !Ref Environment
        GitRev: !Ref GitRev

Parameters:
  DbName:
    Type: String
    Description: Mongodb database name
  MongoSecretName:
    Type: String
    Description: AWS secret name containing Mongodb server secrets
  VPCEndpointId:
    Type: String
    Description: vpc endpoint associated with said APIGW
    AllowedPattern: ^vpce-[A-Za-z0-9]+$
  GitRev:
    Type: String
    Default: ""
  Environment:
    Type: String
    Default: test
    AllowedValues:
      - test
      - prod

Resources:
  AppBackend:
    Type: AWS::Serverless::Function
    Properties:
      MemorySize: 2048
      PackageType: Image
      Policies:
        - AWSSecretsManagerGetSecretValuePolicy:
            SecretArn: !Sub arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${MongoSecretName}*
      Events:
        ListDatasets:
          Type: Api
          Properties:
            Path: /datasets
            Method: post
            RestApiId: !Ref MyRestApi
            Auth:
              Authorizer: MyLambdaRequestAuth
        GetDataset:
          Type: Api
          Properties:
            Path: /datasets/{dataset_id}
            Method: get
            RestApiId: !Ref MyRestApi
            Auth:
              Authorizer: MyLambdaRequestAuth
        PutDataset:
          Type: Api
          Properties:
            Path: /datasets/
            Method: put
            RestApiId: !Ref MyRestApi
            Auth:
              Authorizer: MyLambdaRequestAuth
        DeleteDataset:
          Type: Api
          Properties:
            Path: /datasets/{dataset_id}
            Method: delete
            RestApiId: !Ref MyRestApi
            Auth:
              Authorizer: MyLambdaRequestAuth
#        ListStudies:
#          Type: Api
#          Properties:
#            Path: /studies
#            Method: post
#            RestApiId: !Ref MyRestApi
#            Auth:
#              Authorizer: MyLambdaRequestAuth
#        GetStudy:
#          Type: Api
#          Properties:
#            Path: /studies/{study_id}
#            Method: get
#            RestApiId: !Ref MyRestApi
#            Auth:
#              Authorizer: MyLambdaRequestAuth
#        PutStudy:
#          Type: Api
#          Properties:
#            Path: /studies/
#            Method: put
#            RestApiId: !Ref MyRestApi
#            Auth:
#              Authorizer: MyLambdaRequestAuth
#        DeleteStudy:
#          Type: Api
#          Properties:
#            Path: /studies/{study_id}
#            Method: delete
#            RestApiId: !Ref MyRestApi
#            Auth:
#              Authorizer: MyLambdaRequestAuth
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./functions/be


  MsAuthorizer:
    Type: AWS::Serverless::Function
    Properties:
      MemorySize: 2048
      CodeUri: functions/authorizer/src
      Handler: app.handler
      Runtime: python3.12

  MyRestApi:
    Type: AWS::Serverless::Api
    Properties:
#      BinaryMediaTypes:
#        - application/octet-stream
      Cors:
        AllowOrigin: '''*'''
        AllowHeaders: '''Content-Type,Authorization,X-Amz-Date'''
        MaxAge: '''300'''
      StageName: v1
      TracingEnabled: true
      GatewayResponses:
        MISSING_AUTHENTICATION_TOKEN:
          ResponseTemplates:
            application/json: '{"message": "missing authentication token error OR
              unsupported API method or resource" }'
      MethodSettings:
        - HttpMethod: '*'
          LoggingLevel: INFO
          ResourcePath: /*
          DataTraceEnabled: true
          CachingEnabled: false
          MetricsEnabled: true
      EndpointConfiguration:
        Type: PRIVATE
        VPCEndpointIds:
          - !Ref VPCEndpointId
      Auth:
        Authorizers:
          MyLambdaRequestAuth:
            FunctionPayloadType: TOKEN
            Identity:
              Header: Authorization
            FunctionArn:
              !GetAtt MsAuthorizer.Arn
        ResourcePolicy:
          CustomStatements:
            - Effect: Allow
              Action: execute-api:Invoke
              Resource: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*/*/*"
              Principal: '*'
              Condition:
                StringEquals:
                  aws:SourceVpce: !Ref VPCEndpointId

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions