cli-lib-alpha: unable to bundle NodejsFunction
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
When using the `AwsCdkCli` from the `@aws-cdk/cli-lib-alpha` package I'm unable to synthesise stacks containing a `NodejsFunction` construct.
### Expected Behavior
The stack should synth & deploy normally, provided that all other parameters are valid.
### Current Behavior
When attempting to synth the stack, an error is thrown:
```
Error: Failed to bundle asset cdk-poc-nodejs18x-6e3e8-makeFnIdempotent/my-function/Code/Stage, bundle output is located at /private/var/folders/s7/xzcjrts93cn5_mq16vkcqt794zqxk7/T/cdk.outoC4Vgb/bundling-temp-eb7f12479b9ffbb7cb20787b7437388f75f41b3c18ec89fbfaa0e64470237272-error: TypeError [ERR_INVALID_ARG_VALUE]: The argument 'stdio' is invalid. Received WritableWorkerStdio {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,...
❯ AssetStaging.bundle node_modules/aws-cdk-lib/core/lib/asset-staging.js:2:603
❯ AssetStaging.stageByBundling node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:4544
❯ stageThisAsset node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2005
❯ Cache.obtain node_modules/aws-cdk-lib/core/lib/private/cache.js:1:242
❯ new AssetStaging node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2400
❯ new Asset node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:736
❯ AssetCode.bind node_modules/aws-cdk-lib/aws-lambda/lib/code.js:1:4628
❯ new Function node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:7479
❯ new NodejsFunction node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:1121
```
### Reproduction Steps
1. Create a class that implements `ICloudAssemblyDirectoryProducer`, along the lines of what described in [the construct docs](https://docs.aws.amazon.com/cdk/api/v2/docs/cli-lib-alpha-readme.html#cloud-assembly-directory-producer):
```ts
class MyProducer implements ICloudAssemblyDirectoryProducer {
public app: App;
public stack: Stack;
#stackName: string;
public constructor(stackName: string, context?: Record) {
this.#stackName = stackName;
this.app = new App();
this.stack = new Stack(this.app, this.#stackName);
}
async produce() {
return this.app.synth().directory;
}
}
```
2. Init the provider and cli
```ts
const producer = new MyProducer("cdk-poc-nodejs18x-6e3e8-makeFnIdempotent");
const cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(producer);
```
3. Add resources to the stack
```ts
const table = new Table(producer.stack, "my-table", {
tableName: "my-table",
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
billingMode: BillingMode.PAY_PER_REQUEST,
removalPolicy: RemovalPolicy.DESTROY,
});
const nodeJsFunction = new NodejsFunction(producer.stack, "my-function", {
runtime: Runtime.NODEJS_18_X,
functionName: "my-function-1234",
entry: join(__dirname, `./src/index.ts`),
timeout: Duration.seconds(30),
handler: "handler",
environment: {
IDEMPOTENCY_TABLE_NAME: table.tableName,
},
logRetention: RetentionDays.ONE_DAY,
});
table.grantReadWriteData(nodeJsFunction);
```
4. Synth the stack
```ts
await cli.synth({
stacks: [producer.stack.stackName],
});
```
5. create a function file in `src/index.ts`
```ts
export const handler = async () => { return { statusCode: 200 } };
```
6. run & see the error
Full file below
```ts
import { App, Stack, RemovalPolicy, Duration } from "aws-cdk-lib";
import { Table, AttributeType, BillingMode } from "aws-cdk-lib/aws-dynamodb";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { Runtime } from "aws-cdk-lib/aws-lambda";
import { RetentionDays } from "aws-cdk-lib/aws-logs";
import { join } from "node:path";
import {
AwsCdkCli,
ICloudAssemblyDirectoryProducer,
} from "@aws-cdk/cli-lib-alpha";
const producer = new MyProducer("cdk-poc-nodejs18x-6e3e8-makeFnIdempotent");
const cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(producer);
const table = new Table(producer.stack, "my-table", {
tableName: "my-table",
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
billingMode: BillingMode.PAY_PER_REQUEST,
removalPolicy: RemovalPolicy.DESTROY,
});
const nodeJsFunction = new NodejsFunction(producer.stack, "my-function", {
runtime: Runtime.NODEJS_18_X,
functionName: "my-function-1234",
entry: join(__dirname, `./src/index.ts`),
timeout: Duration.seconds(30),
handler: "handler",
environment: {
IDEMPOTENCY_TABLE_NAME: table.tableName,
},
logRetention: RetentionDays.ONE_DAY,
});
table.grantReadWriteData(nodeJsFunction);
await cli.synth({
stacks: [producer.stack.stackName],
});
```
Alternatively, clone this repo with the same code as above and run: https://github.com/dreamorosi/cdk-cli-poc
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### CDK CLI Version
2.87.0
### Framework Version
_No response_
### Node.js Version
v18.12.1
### OS
macOS
### Language
Typescript
### Language Version
5.1.6
### Other information
_No response_
Contributor guide
Research direction
Reproduce the failure using the linked cdk-cli-poc or the TypeScript example, then trace AwsCdkCli.fromCloudAssemblyDirectoryProducer through cli.synth and NodejsFunction bundling. The fix is complete when a stack containing NodejsFunction can synthesize successfully without the invalid stdio error, with coverage added for this path if the repository’s existing tests identify an appropriate location.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, node.js, typescript
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100