Skip to content

❗NOTICE (aws-lambda-nodejs): Cannot find defining file #34486

Closed
@CDillinger

Description

@CDillinger

Please add your +1 👍 to let us know you have encountered this

Status: IN-PROGRESS

Overview:

Instantiation of NodejsFunction fails when the entry property is not passed

The addition of the @propertyInjectable decorator onto NodejsFunction breaks it because it alters the callstack, which is inspected inside the construct to automagically determine the entrypoint of the function.

Additional details:

The error comes from the findDefiningFile() function which is responsible for locating the source file where the NodejsFunction is defined. Here's the problematic code:

function findDefiningFile(): string {
let definingIndex;
const sites = callsites();
for (const [index, site] of sites.entries()) {
if (site.getFunctionName() === 'NodejsFunction') {
// The next site is the site where the NodejsFunction was created
definingIndex = index + 1;
break;
}
}
if (!definingIndex || !sites[definingIndex]) {
throw new Error('Cannot find defining file.');
}
return sites[definingIndex].getFileName();
}

The function attempts to find the location where NodejsFunction was instantiated by:

  1. Getting the call stack using callsites()
  2. Looking for a function named 'NodejsFunction'
  3. Taking the next entry in the stack as the defining file

The issue appears to be that the stack trace analysis is failing to identify the correct entry point, possibly due to changes in how the code is bundled or how the stack trace is generated in the newer version.

Affected version is 2.196.0. Reverting to 2.195.0 gets synthesis to succeed again.

Complete Error Message:

Error: Cannot find defining file.
    at findDefiningFile (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:6641)
    at findEntry (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:5364)
    at new NodejsFunction2 (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:2576)
    at new NodejsFunction2 (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/core/lib/prop-injectable.js:1:488)
    at new PublicApi (/Users/collin/repos/my-cdk-project/lib/public-api/api.ts:14:21)
    at new PublicApiStack (/Users/collin/repos/my-cdk-project/lib/stacks/public-api-stack.ts:9:5)
    at new PublicApiProdStage (/Users/collin/repos/my-cdk-project/lib/stacks/pipeline-stack.ts:10:5)
    at new PublicApiPipelineStack (/Users/collin/repos/my-cdk-project/lib/stacks/pipeline-stack.ts:22:18)
    at Object.<anonymous> (/Users/collin/repos/my-cdk-project/lib/app.ts:14:3)
    at Module._compile (node:internal/modules/cjs/loader:1376:14)

Workaround:

As a workaround, one could pass the entry property to avoid this error:

    const handler = new NodejsFunction(this, "handler", {
      runtime: Runtime.NODEJS_20_X,
      timeout: Duration.seconds(30),
      // explicitly point to the location of your entrypoint
      entry: /path/to/entry.ts
    });

Solution:

Related Issues:

Describe the bug

After dependabot updated aws-cdk-lib to 2.196.0, two different projects of mine started failing synthesis. Reverting to 2.195.0 gets synthesis to succeed again.

It appears to be an issue with the NodejsFunction class. I believe this commit to be the cause: 8ee4427

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Library Version

2.195.0

Expected Behavior

Synthesis should succeed instead of an error being thrown.

Current Behavior

Running cdk synth fails with the following error:

Error: Cannot find defining file.
    at findDefiningFile (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:6641)
    at findEntry (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:5364)
    at new NodejsFunction2 (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:2576)
    at new NodejsFunction2 (/Users/collin/repos/my-cdk-project/node_modules/aws-cdk-lib/core/lib/prop-injectable.js:1:488)
    at new PublicApi (/Users/collin/repos/my-cdk-project/lib/public-api/api.ts:14:21)
    at new PublicApiStack (/Users/collin/repos/my-cdk-project/lib/stacks/public-api-stack.ts:9:5)
    at new PublicApiProdStage (/Users/collin/repos/my-cdk-project/lib/stacks/pipeline-stack.ts:10:5)
    at new PublicApiPipelineStack (/Users/collin/repos/my-cdk-project/lib/stacks/pipeline-stack.ts:22:18)
    at Object.<anonymous> (/Users/collin/repos/my-cdk-project/lib/app.ts:14:3)
    at Module._compile (node:internal/modules/cjs/loader:1376:14)

Reproduction Steps

file api.ts:

import { Construct } from "constructs";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { LambdaRestApi } from "aws-cdk-lib/aws-apigateway";
import { Runtime } from "aws-cdk-lib/aws-lambda";
import { Duration } from "aws-cdk-lib";

export class PublicApi extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const handler = new NodejsFunction(this, "handler", {
      runtime: Runtime.NODEJS_20_X,
      timeout: Duration.seconds(30),
    });
    new LambdaRestApi(this, "public-api", {
      handler,
      proxy: true,
    });
  }
}

file api.handler.ts:

import {
  APIGatewayProxyResult,
  APIGatewayEvent,
} from "aws-lambda";

export const handler = async (
  event: APIGatewayEvent,
): Promise<APIGatewayProxyResult> => {
  return {
    statusCode: 200,
    body: "hello world",
  };
}

Possible Solution

No response

Additional Information/Context

No response

AWS CDK Library version (aws-cdk-lib)

2.196.0

AWS CDK CLI version

2.1016.0

Node.js Version

20.x

OS

Mac OS

Language

TypeScript

Language Version

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    @aws-cdk/aws-lambda-nodejsbugThis issue is a bug.effort/mediumMedium work item – several days of effortp0potential-regressionMarking this issue as a potential regression to be checked by team member

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions