Skip to content

Bug: start-api does not use correct function when duplicate resource / construct ids in CDK #8275

@jrbarnard

Description

@jrbarnard

Description:

When running sam local start-api with a CDK synthed template, it finds the wrong Lambda function to run, this is due to a Serverless::Function with a logical ID of Lambda and a Lambda::Function generated by CDK whose resource id (in the cdk path) is Lambda.
The resource metadata normalizer uses the resource id from the cdk path if it's there meaning there is conflict.

The logic doing the cdk path extraction is within get_resource_id, that is then set to the SamResourceId which is then used in place of the logical ID when doing function extraction.

There are a couple of mitigations we can look at that I'm aware of:

  • Explicitly set a SamResourceId on the Lambda function - this seems unecessary just to get it running locally
  • Change the resource ids / logical ids - this will cause redeployment, again seems unecessary to get it running locally

Steps to reproduce:

  • Create a CDK stack with two lambda functions, both Resource IDs should be Lambda, one should be nested in a sub construct
  • Set up a rest api to point to the first lambda

E.g.

new Function(this, 'Lambda', {
    code: Code.fromInline(`
        exports.handler = (event, context, callback) => {
            callback(null, "Hello World!");
        };
    `),
    description: `test`,
    runtime: Runtime.NODEJS_22_X,
    handler: 'handler.handle',
  });

Observed result:

  • It runs the second function instead of the one linked to the API
  • I've run it with debug and gone through the code and I can see during the function detection stage it pulls out the resource ID from the cdk path and uses that as the SamResourceId that is then used when identifying functions for invoke

Expected result:

  • It should run the API function code even if they share a resource ID
  • I'd expect this normalisation function to take into account nested resources so we don't end up with duplicate ids - is there any reason we can't always just use logical IDs?

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

{
  "version": "1.139.0",
  "system": {
    "python": "3.13.3",
    "os": "macOS-15.6.1-arm64-arm-64bit-Mach-O"
  },
  "additional_dependencies": {
    "docker_engine": "27.4.0",
    "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_PACKAGE_PERFORMANCE",
    "SAM_CLI_BETA_RUST_CARGO_LAMBDA"
  ]
}

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