Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: synth fails if cdk.out does not exist #3717

Closed
rgd11 opened this issue Aug 19, 2019 · 16 comments · Fixed by #16670
Closed

cli: synth fails if cdk.out does not exist #3717

rgd11 opened this issue Aug 19, 2019 · 16 comments · Fixed by #16670
Labels
bug This issue is a bug. effort/medium Medium work item – several days of effort p2 package/tools Related to AWS CDK Tools or CLI

Comments

@rgd11
Copy link

rgd11 commented Aug 19, 2019

🐛 Bug Report

What is the problem?

cdk synth returns ENOENT: no such file or directory, open 'cdk.out/manifest.json' when the cdk.out directory is not present.

However, this results in the creation of a default manifest.json, and subsequent calls to synth succeed

Reproduction Steps

from cdk project directory:

  1. mvn clean
  2. rm -rf cdk.out
  3. mvn compile
  4. cdk synth

Verbose Log

xxxxxxxxx:cdk xxxxxxxx$ ls
cdk.json        cdk.out         pom.xml         src             target
xxxxxxxxx:cdk xxxxxxxx$ mvn clean
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.xxx.xxx:project >--------------------
[INFO] Building project 0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ project ---
[INFO] Deleting /Users/xxxxxxxx/workspace/xxxxxxxx/cdk/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.303 s
[INFO] Finished at: 2019-08-19T16:27:07-07:00
[INFO] ------------------------------------------------------------------------
xxxxxxxxx:cdk xxxxxxxx$ rm -rf cdk.out
xxxxxxxxx:cdk xxxxxxxx$ mvn compile
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.xxx.xxx:project >--------------------
[INFO] Building project 0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ project ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/xxxxxxxx/workspace/xxxxxxxx/cdk/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to /Users/xxxxxxxx/workspace/xxxxxxxx/cdk/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.835 s
[INFO] Finished at: 2019-08-19T16:27:24-07:00
[INFO] ------------------------------------------------------------------------
xxxxxxxxx:cdk xxxxxxxx$ cdk synth
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.xxx.xxx:project >--------------------
[INFO] Building project 0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ project ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.574 s
[INFO] Finished at: 2019-08-19T16:27:31-07:00
[INFO] ------------------------------------------------------------------------
ENOENT: no such file or directory, open 'cdk.out/manifest.json'

Environment

  • CDK CLI Version: 1.4.0 (build 175471f)
  • Module Version:
  • OS: OSX Mojave
  • Language: Java

Other information

@rgd11 rgd11 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 19, 2019
@nija-at
Copy link
Contributor

nija-at commented Aug 21, 2019

Unable to reproduce.

I ran the following commands on my Mac (OSX Mojave) running cdk version 1.4.0

$ cdk init app --language=java
...

$mvn compile
...

$ mvn clean && rm -rf cdk.out

$ mvn compile
...

$ cdk synth
Successfully synthesized to /Users/nija/workplace/cdk/hello-cdk-java/cdk.out
Supply a stack name (hello-cdk-1, hello-cdk-2) to display its template.

I can also confirm that cdk.out/ contains the synthesized templates in JSON.

@nija-at nija-at added needs-response and removed needs-triage This issue or PR still needs to be triaged. labels Aug 21, 2019
@nija-at nija-at self-assigned this Aug 21, 2019
@nija-at nija-at added closing-soon This issue will automatically close in 4 days unless further comments are made. and removed needs-response labels Aug 22, 2019
@bakenator
Copy link

I was getting this error as well. Went away when I updated my cdk.ts file to the base example file. So some error in the cdk.ts code may be causing this.

@shivlaks shivlaks changed the title synth fails if cdk.out does not exist cli: synth fails if cdk.out does not exist Aug 26, 2019
@shivlaks shivlaks added the package/tools Related to AWS CDK Tools or CLI label Aug 26, 2019
@shivlaks
Copy link
Contributor

I also took a run at reproducing this issue and wasn't able to get to the error on 1.5.0 - similar steps outline in the issue and @nija-at specified.

Mac OS X (Mojave 10.14.6)

Are you still running into this issue?

@nija-at
Copy link
Contributor

nija-at commented Jan 8, 2020

Thanks to @ivoanjo who also had this problem, I'm able to reproduce this in Java.

I was able to reproduce this using our standard sample-app package from cdk init -l=java and modify the code to drop app.synth(). Running cdk synth on this when there's no cdk.out/ folder gets this error.

There seems to be some race condition between the cdk.out/ folder being generated and when the CLI expects it to be present for parsing. This specifically happens when the app does not call app.synth().

For those encountering this issue, the workaround is for your app to call app.synth() at the end of the program.

@nija-at nija-at reopened this Jan 8, 2020
@nija-at nija-at assigned shivlaks and unassigned nija-at Jan 8, 2020
@shivlaks shivlaks added p2 and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Jan 9, 2020
@saltman424
Copy link
Contributor

I am having the same problem. However, the cause of the problem seems to differ in that in my case, it occurs whenever I specify an outdir other than cdk.out, whether or not I call app.synth().

I created a separate issue for this (#5815), since I think the cause is different. But the relevant details from that issue are copied below.

If I synthesize without a modified outdir (producing a cdk.out/mainfest.json), and then synthesize with a modified outdir, it successfully outputs the expected files to the modified outdir. So it seems that at some point during the process it needs to read from cdk.out/manifest.json, whether or not the outdir property is set to cdk.out, and then it proceeds to behave as expected.

It also appears that a cdk.out folder is created when running cdk synth with a modified outdir.

Additionally, it seems that in at least one project where I am having this issue, running 'cdk deploy' deploys the templates in cdk.out, not the specified outdir. So it seems like currently the outdir is just not really useful.

Is it possible that 'cdk.out' is hard-coded somewhere?

@shivlaks shivlaks added the effort/medium Medium work item – several days of effort label Jan 29, 2020
@thekevinbrown
Copy link

thekevinbrown commented Jan 31, 2020

I'm having this issue in a Lerna monorepo with Typescript:

$ cdk synth --verbose
CDK toolkit version: 1.22.0 (build 309ac1b)
Command line arguments: { _: [ 'synth' ],
  verbose: true,
  v: true,
  'ignore-errors': false,
  ignoreErrors: false,
  json: false,
  j: false,
  ec2creds: undefined,
  i: undefined,
  'version-reporting': undefined,
  versionReporting: undefined,
  'path-metadata': true,
  pathMetadata: true,
  'asset-metadata': true,
  assetMetadata: true,
  'role-arn': undefined,
  r: undefined,
  roleArn: undefined,
  staging: true,
  'no-color': false,
  noColor: false,
  fail: false,
  '$0':
   '[project directory]/node_modules/.bin/cdk' }
Determining whether we're on an EC2 instance.
Does not look like EC2 instance.
cdk.json: {
  "app": "ts-node src/index.ts"
}
merged settings: { versionReporting: true,
  pathMetadata: true,
  output: 'cdk.out',
  app: 'ts-node src/index.ts',
  context: {},
  tags: [],
  assetMetadata: true,
  toolkitBucket: {},
  staging: true }
Setting "CDK_DEFAULT_REGION" environment variable to ap-southeast2
Resolving default credentials
Retrieved account ID [my account ID] from disk cache
Setting "CDK_DEFAULT_ACCOUNT" environment variable to [my account ID]
context: { 'aws:cdk:enable-path-metadata': true,
  'aws:cdk:enable-asset-metadata': true }
outdir: cdk.out
env: { CDK_DEFAULT_REGION: 'ap-southeast2',
  CDK_DEFAULT_ACCOUNT: '[my account ID]',
  CDK_CONTEXT_JSON:
   '{"aws:cdk:enable-path-metadata":true,"aws:cdk:enable-asset-metadata":true}',
  CDK_OUTDIR: 'cdk.out',
  CDK_CLI_ASM_VERSION: '1.21.0',
  CDK_CLI_VERSION: '1.22.0' }
ENOENT: no such file or directory, open 'cdk.out/manifest.json'
Error: ENOENT: no such file or directory, open 'cdk.out/manifest.json'
    at Object.openSync (fs.js:443:3)
    at Object.readFileSync (fs.js:343:35)
    at new CloudAssembly ([project directory]/node_modules/@aws-cdk/cx-api/lib/cloud-assembly.ts:77:36)
    at Object.execProgram ([project directory]/node_modules/aws-cdk/lib/api/cxapp/exec.ts:85:10)
    at process._tickCallback (internal/process/next_tick.js:68:7)

If I create the file myself then it complains that it can't parse the version out of it, etc. I'm not sure why, and when I run the default app --language=typescript starter, synth runs fine, so it's definitely something about my specific code, but I'm not sure what yet.

@thekevinbrown
Copy link

For me the issue was that I had missed the difference between the file in bin and the file in lib, so I was missing:

const app = new cdk.App();
new MyStack(app, 'MyStack');

As soon as I added that back in I stopped getting the error about the missing file. It'd be great if we could improve the error message in this case.

@joekiller
Copy link

This may help some people on MacOS. I was having a hard time occasionally with this and it turned out that my script set TMPDIR at some point and then deleted that directory. Later on nodejs picked that up and tries to extract stuff to TMPDIR and we end up with Error: ENOENT: no such file or directory, mkdtemp errors.

@flashflexpro
Copy link

this is such a great idea but rather disappointing implementation:
I'm using 1.57, both Java and TS, completely following the cdk init command, hardly adding few lines of code:

Java project blocked:
ENOENT: no such file or directory, open 'cdk.out\manifest.json' Error: ENOENT: no such file or directory, open 'cdk.out\manifest.json' at Object.openSync (fs.js:458:3) at Object.readFileSync (fs.js:360:35) at Function.loadManifest (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\node_modules\@aws-cdk\cloud-assembly-schema\lib\manifest.ts:128:29) at Function.loadAssemblyManifest (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\node_modules\@aws-cdk\cloud-assembly-schema\lib\manifest.ts:44:21) at Function.load (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\node_modules\@aws-cdk\cloud-assembly-schema\lib\manifest.ts:83:81) at new CloudAssembly (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\node_modules\@aws-cdk\cx-api\lib\cloud-assembly.ts:52:39) at createAssembly (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\lib\api\cxapp\exec.ts:79:14) at Object.execProgram (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\lib\api\cxapp\exec.ts:75:10) at processTicksAndRejections (internal/process/task_queues.js:97:5) at CloudExecutable.doSynthesize (C:\Users\annmsmn\.npm\node-v12.16.3-win-x64\node_modules\aws-cdk\lib\api\cxapp\cloud-executable.ts:66:24)

then blocked completely by:

unable to determine cloud assembly output directory. Assets must be defined indirectly within a "Stage" or an "App" scope Subprocess exited with error 1 Error: Subprocess exited with error 1 at ChildProcess.<anonymous> (/home/ubuntu/.nvm/versions/node/v12.18.3/lib/node_modules/aws-cdk/lib/api/cxapp/exec.ts:118:23) at ChildProcess.emit (events.js:315:20) at ChildProcess.EventEmitter.emit (domain.js:483:12) at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)

when use

    const lambdaSrc = new lambda.AssetCode("lambda/src");

@flashflexpro
Copy link

flashflexpro commented Aug 11, 2020

Also there is bug generating excessive file name after adding one line of code:

        // The code that defines your stack goes here

/*
        new Function( this, "lambda", FunctionProps.builder()
                .functionName( "tmp-tst135" )
                .runtime( Runtime.NODEJS_12_X )
                .code( Code.fromAsset( "", ))
                .environment( Map.of( "aaa", "kkk" ))
                .handler( "abc-handler" )
                .build() );*/
Exception in thread "main" software.amazon.jsii.JsiiException: ENAMETOOLONG: name too long, mkdir 'cdk.out\asset.42fc811dc4603f26682bbbd201e828a9dbc87016180ebacd900cd8519f1d7c5c\cdk.out\asset.42fc811dc4603f26682bbbd201e828a9dbc87016180ebacd900cd8519f1d7c5

@NGL321 NGL321 assigned rix0rrr and unassigned shivlaks Jan 25, 2021
@wysird
Copy link

wysird commented May 6, 2021

I was getting the same error.

  • OpenJDK 14
  • macOS Catalina 10.15.7
  • cdk 1.102.0 (build a75d52f)
  • node v14.5.0
  • npm 6.14.5

Code:

import software.amazon.awscdk.core.App;
...
public static void main(final String... args) {
    App app = new App();
    new MyStack(...);
}
$ rm -r cdk.out
$ mvn clean compile
...
$ cdk synth
ENOENT: no such file or directory, open 'cdk.out/manifest.json'

However, after adding app.synth(); to the end of my main method:

import software.amazon.awscdk.core.App;

...

public static void main(final String... args) {
    App app = new App();
    new MyStack(...);

    app.synth();     // NEW LINE
}

I then got the expected output when running cdk synth:

$ rm -r cdk.out
$ mvn clean compile
...
$ cdk synth
Resources:
...

So check that you have app.synth() after your resource definitions. I'm not sure why this worked for me, I haven't done a deeper dive than this (because it now works for me) but wanted to share.

Hope this is helpful in some way.

@rix0rrr rix0rrr removed their assignment Jun 3, 2021
@shellscape
Copy link

@shivlaks @SomayaB it looks like ya'll closed #5815 to track the issue here, but it doesn't look like it's actually being tracked. this has been a persistent issue for a year and a half now. would be really cool if one of the maintainers there at AWS could give this a look. outdir (or --output) is crucial for parallel deployments, but it's unusable due to this bug.

@shellscape
Copy link

shellscape commented Sep 24, 2021

This is the offending line

this.manifest = cxschema.Manifest.loadAssemblyManifest(path.join(directory, MANIFEST_FILE));

I've added logging there and can confirm that it's called twice; once with the correct custom outdir I'm providing, and once with the incorrect cdk.out:

AWS: CloudAssembly.directory: /Users/<me>/backend/cdk.out/cron-refresh-views/1632494932295 
AWS: CloudAssembly.directory: cdk.out 

I'll continue to trace this and will follow up.

Update

So you can see here that the correct call has a completely different stack trace than the incorrect call, meaning that we've got one entity behaving properly and instantiating the CloudAssembly class correctly, and one that isn't:

Correct:

AWS: CloudAssembly.directory: /Users/<me>/backend/cdk.out/cron-refresh-views/1632495205471
Error: Capture CloudAssembly Stack
    at new CloudAssembly (/Users/<me>/backend/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/cx-api/lib/cloud-assembly.ts:38:10)
    at CloudAssemblyBuilder.buildAssembly (/Users/<me>/backend/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/cx-api/lib/cloud-assembly.js:278:16)
    at Object.synthesize (/Users/<me>/backend/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/core/lib/private/synthesis.ts:41:18)
    at App.synth (/Users/<me>/backend/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/core/lib/stage.ts:94:23)
    at process.<anonymous> (/Users/<me>/backend/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/core/lib/app.ts:64:45)
    at Object.onceWrapper (events.js:422:26)
    at process.emit (events.js:315:20)
    at process.EventEmitter.emit (domain.js:467:12)
    at process.emit (/Users/<me>/backend/node_modules/.pnpm/[email protected]/node_modules/source-map-support/source-map-support.js:516:21)

Incorrect:

AWS: CloudAssembly.directory: cdk.out
Error: Capture CloudAssembly Stack
    at new CloudAssembly (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/@[email protected]/node_modules/@aws-cdk/cx-api/lib/cloud-assembly.ts:38:10)
    at createAssembly (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/api/cxapp/exec.ts:83:14)
    at Object.execProgram (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/api/cxapp/exec.ts:79:10)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at CloudExecutable.doSynthesize (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/api/cxapp/cloud-executable.ts:67:24)
    at CloudExecutable.synthesize (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/api/cxapp/cloud-executable.ts:53:29)
    at CdkToolkit.selectStacksForDeploy (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/cdk-toolkit.ts:401:22)
    at CdkToolkit.deploy (/Users/<me>/.nvm/versions/node/v14.15.3/pnpm-global/5/node_modules/.pnpm/[email protected]/node_modules/aws-cdk/lib/cdk-toolkit.ts:115:20)
    at initCommandLine (/Use

@shellscape
Copy link

shellscape commented Sep 24, 2021

Here's the offending block in the aws-cdk pacakge:

debug('outdir:', outdir);
env[cxapi.OUTDIR_ENV] = outdir;
// Send version information
env[cxapi.CLI_ASM_VERSION_ENV] = cxschema.Manifest.version();
env[cxapi.CLI_VERSION_ENV] = versionNumber();
debug('env:', env);
await exec();
return createAssembly(outdir);
function createAssembly(appDir: string) {
try {
return new cxapi.CloudAssembly(appDir);
} catch (error) {
if (error.message.includes(cxschema.VERSION_MISMATCH)) {
// this means the CLI version is too old.
// we instruct the user to upgrade.
throw new Error(`This CDK CLI is not compatible with the CDK library used by your application. Please upgrade the CLI to the latest version.\n(${error.message})`);
}
throw error;
}
}

The code looks for output on the command line and disregards the AppProps.outdir passed in code. That means in order to resolve this, you have to set both outdir in the AppProps during instantiation of the App, as well as use --outdir set to the same exact value, or completely rely on --output. Any way you go, --output is required. This is very redundant, and makes using dynamic output directories a massive pain. Not remotely ideal.

@rix0rrr @shivlaks @SomayaB There's the triage. Can we get a fix or some documentation around this?

@rix0rrr
Copy link
Contributor

rix0rrr commented Sep 27, 2021

I don't think setting AppProps.outdir can even work, as the CLI won't know where to look for the Cloud Assembly.

Now that you mention it, I'm not sure why we have that property in the first place. I guess it is for unit tests.

@eladb you added this property in #2636... do you happen to remember why it is configurable from inside the CDK app?

rix0rrr added a commit that referenced this issue Sep 27, 2021
If this property is passed it has to agree with the CLI's `--output` flag.

If this property is not passed, it will default to the CLI's `--output`
flag.

In either case, it's better to just use `--output` and not pass this
property at all; the property only has value inside tests.

Fixes #3717.
@mergify mergify bot closed this as completed in #16670 Oct 27, 2021
mergify bot pushed a commit that referenced this issue Oct 27, 2021
If this property is passed it has to agree with the CLI's `--output` flag.

If this property is not passed, it will default to the CLI's `--output`
flag.

In either case, it's better to just use `--output` and not pass this
property at all; the property only has value inside tests.

I tried to add validation (by using `Annotations.of(app).addWarning()` but they are
useless anyway: in the CX protocol, metadata can only be attached to `StackArtifacts`,
so metadata attached to the `App` will not be rendered.

Adding a full framework feature to move metadata to a different place feels like too much
risk and work for this small note, so turned it into a documentation fix.

Fixes #3717.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️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.

TikiTDO pushed a commit to TikiTDO/aws-cdk that referenced this issue Feb 21, 2022
If this property is passed it has to agree with the CLI's `--output` flag.

If this property is not passed, it will default to the CLI's `--output`
flag.

In either case, it's better to just use `--output` and not pass this
property at all; the property only has value inside tests.

I tried to add validation (by using `Annotations.of(app).addWarning()` but they are
useless anyway: in the CX protocol, metadata can only be attached to `StackArtifacts`,
so metadata attached to the `App` will not be rendered.

Adding a full framework feature to move metadata to a different place feels like too much
risk and work for this small note, so turned it into a documentation fix.

Fixes aws#3717.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. effort/medium Medium work item – several days of effort p2 package/tools Related to AWS CDK Tools or CLI
Projects
None yet
Development

Successfully merging a pull request may close this issue.