aws-cdk: [core] Unable to Synthesize CDK in 1.57: Assets must be defined indirectly within a "Stage" or an "App" scope

After upgrading to 1.57 I get the following error when trying to synthesize my application:

unable to determine cloud assembly output directory. Assets must be defined indirectly within a "Stage" or an "App" scope

I tried specifying outdir in my App as well as my Stage, but neither works (in App throws same error, in Stage throws nested stage error).

Reproduction Steps

I haven’t quite nailed down the triggering code, but here’s my general setup:

export interface MyStackProps extends cdk.StackProps {
    source: s3deploy.ISource;
    code: lambda.Code;
}

class MyStack extends cdk.Stack {
    constructor(scope: cdk.Construct, props: MyStackProps) {
        super(scope, "MyStack", props)

       ...

        new lambda.Function(this, "ApiHandler", {
          code: props.code,
        });

        new s3deploy.BucketDeployment(this, "DeployWithInvalidation", {
          sources: [props.source],
          destinationBucket: someDistributionBucket,
          distribution: someDistribution,
        });
    }
}

class MyStage extends cdk.Stage {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StageProps) {
    super(scope, id, props);

    new MyStack(this, {
       // Changing these values to `{} as any` still throws the same scope error
        code:  lambda.Code.fromAsset("../api/dist"),
        source: s3deploy.Source.asset("../app/build"),
    });
  }
}

class PipelineStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const sourceArtifact = new codepipeline.Artifact();
    const cloudAssemblyArtifact = new codepipeline.Artifact("CloudAssemblyArtifact");

    const pipeline = new pipelines.CdkPipeline(this, "Pipeline", {
      pipelineName: "MyAppPipeline",
      cloudAssemblyArtifact,

      sourceAction: new codepipeline_actions.GitHubSourceAction({...}),

      synthAction: pipelines.SimpleSynthAction.standardNpmSynth({
        sourceArtifact,
        cloudAssemblyArtifact,
        ...
      }),
    });

    pipeline.addApplicationStage(new MyStage(this, "Prod"));
  }
}

const app = new cdk.App();
new PipelineStack(app, "PipelineStack");

What did you expect to happen?

The CDK app synthesizes correctly.

What actually happened?

Synthesis fails with the message unable to determine cloud assembly output directory. Assets must be defined indirectly within a "Stage" or an "App" scope

Environment

  • CLI Version : 1.57
  • Framework Version: 1.57
  • Node.js Version: v14.3.0
  • OS : Ubuntu (on WSL2)
  • Language (Version): TypeScript (3.9.7)

Other

Here’s where the error is being thrown


This is 🐛 Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 36 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I had the same issue and fixed it with these steps:

  1. Set version of all cdk related packages to “ˆ1.59.0”
"devDependencies": {
  "@aws-cdk/assert": "^1.59.0",
  "@types/jest": "^25.2.1",
  "@types/node": "10.17.5",
  "aws-cdk": "^1.59.0",
  "jest": "^25.5.0",
  "ts-jest": "^25.3.1",
  "ts-node": "^8.1.0",
  "typescript": "~3.7.2"
},
"dependencies": {
  "@aws-cdk/aws-apigateway": "^1.59.0",
  "@aws-cdk/aws-codepipeline": "^1.59.0",
  "@aws-cdk/aws-codepipeline-actions": "^1.59.0",
  "@aws-cdk/aws-lambda": "^1.59.0",
  "@aws-cdk/core": "^1.59.0",
  "@aws-cdk/pipelines": "^1.59.0",
  "@types/aws-lambda": "^8.10.61",
  "source-map-support": "^0.5.16"
}
  1. Delete both node_modules and package-lock.json

  2. Run npm install

I had this problem in v1.58.0 when following the CDK Pipelines blog post. I have a local npm package reference (file:…/etc) as well. Removing the local package did not fix it, but downgrading to pinned 1.56.0 fixed it for me, even when reintroducing the local package.

Maybe this issue should be reopened?

Just managed to reporoduce this in a clean AWS CDK app without any relative packages in package.json. I have a clean stack with only the following construct:

new lambda.Function(this, 'js', {
                handler: "handler",
                runtime: lambda.Runtime.NODEJS_12_X,
                code: lambda.Code.fromAsset(path.resolve(__dirname, './../lambda/js'))
            });

Versions:

  "devDependencies": {
    "@aws-cdk/assert": "1.45.0",
    "@types/jest": "^25.2.1",
    "@types/node": "10.17.5",
    "aws-cdk": "^1.57.0",
    "jest": "^25.5.0",
    "ts-jest": "^25.3.1",
    "ts-node": "^8.1.0",
    "typescript": "~3.7.2"
  },
  "dependencies": {
    "@aws-cdk/aws-lambda-nodejs": "^1.57.0",
    "@aws-cdk/core": "^1.57.0",
    "source-map-support": "^0.5.16"
  }

There seems to be another issue with semvar dependencies using the hat symbol `^. For example:

"devDependencies": {
    "@aws-cdk/assert": "^1.68.0",
    "aws-cdk": "^1.68.0",
  },
  "dependencies": {
    "@aws-cdk/aws-waf": "^1.68.0",
    "@aws-cdk/core": "^1.68.0",
    "@aws-solutions-constructs/aws-cloudfront-s3": "^1.68.0",
  }

Steps:

  • Removing node_modules
  • Removing package-lock.json
  • running npm install

Then looking at the package-lock.json I see it’s installed 1.69.0 somehow:

"dependencies": {
    "@aws-cdk/assert": {
      "version": "1.69.0",
      "resolved": "https://registry.npmjs.org/@aws-cdk/assert/-/assert-1.69.0.tgz",
      "integrity": "sha512-VGjF1sNx05ez5/dwQ8Gn1Bc72X4Tjg1zOPRXq/1LOan2PFWz7WiwHvpww85dRWK1N0R462k6ntUshU8U3TSOBA==",
      "dev": true,
      "requires": {
        "@aws-cdk/cloud-assembly-schema": "1.69.0",
        "@aws-cdk/cloudformation-diff": "1.69.0",
        "@aws-cdk/core": "1.69.0",
        "@aws-cdk/cx-api": "1.69.0",
        "constructs": "^3.0.4"
      }
    }

If I lock my dependencies by removing the hat symbols ^ from versions e.g.:

"devDependencies": {
    "@aws-cdk/assert": "1.68.0",
    "aws-cdk": "1.68.0",
  },
  "dependencies": {
    "@aws-cdk/aws-waf": "1.68.0",
    "@aws-cdk/core": "1.68.0",
    "@aws-solutions-constructs/aws-cloudfront-s3": "1.68.0",
  }

Then it installs correctly:


"dependencies": {
    "@aws-cdk/assert": {
      "version": "1.68.0",
      "resolved": "https://registry.npmjs.org/@aws-cdk/assert/-/assert-1.68.0.tgz",
      "integrity": "sha512-KHL0Z+7jzGzpZnjlCXmGONS0nBecU4eMWOQaUaMXtzQ5iwEEMq/GCwdy59m0TM919UQi3RgPvGV+YPY/Laptxg==",
      "dev": true,
      "requires": {
        "@aws-cdk/cloud-assembly-schema": "1.68.0",
        "@aws-cdk/cloudformation-diff": "1.68.0",
        "@aws-cdk/core": "1.68.0",
        "@aws-cdk/cx-api": "1.68.0",
        "constructs": "^3.0.4"
      }
    },

This fixed the issue I was having

@jonny-rimek This really helped. I aligned version of all packages, eliminated node_modules and package-lock.json and I had to reinstall aws-cdk because it wasn’t updated to last version. And it works… So I suppose in my case one part of the problem was old (1.32.0) version of aws-cdk installed on my machine. Thanks

As far as I can tell the error is caused by some dependencies being pinned and and some aren’t, when you create a new repo with cdk init.

I fixed it by unpinning all dependencies, deleting node_modules and deleting package-lock.json.

{
  ...
  "devDependencies": {
    "@aws-cdk/assert": "^1.62.0",
    "@types/jest": "^26.0.13",
    "@types/node": "10.17.27",
    "aws-cdk": "^1.62.0",
    "jest": "^26.0.4",
    "ts-jest": "^26.1.3",
    "ts-node": "^8.1.0",
    "typescript": "~3.9.6"
  },
  "dependencies": {
    "@aws-cdk/aws-ec2": "^1.62.0",
    "@aws-cdk/aws-ecs": "^1.62.0",
    "@aws-cdk/aws-ecs-patterns": "^1.62.0",
    "@aws-cdk/aws-rds": "^1.62.0",
    "@aws-cdk/aws-s3": "^1.62.0",
    "@aws-cdk/core": "^1.62.0",
    "source-map-support": "^0.5.16"
  }
}

rm package-lock.json rm -rf node_modules

worked perfectly.

@billmcknight1953 I had both errors and fixed both with the above steps

I can confirm @Dzhuneyt 's experience

The error I am getting is with Code.fromAssetPath in a use case similar to @tneely with an examples subdirectory.

            code: lambda.Code.fromAsset(path.resolve(__dirname, './../lambda/js'))

Updating to 1.60 and doing a clean of package-lock.json and node-modules with a clean install didn’t resolve things. If I update the lambda to use an inline block of code it doesn’t fail.

Two of us at my company got this error message when closely implementing this CDK Pipelines blog post. In our case the problem was due to a package.json entry for aws-cdk/core of “1.57.0” while all the other CDK packages were “^1.57.0”.

Once the packages are all aligned, of course, you should delete your node_modules, and package.lock.json, and perform a npm install. The error message implies a cloud assembly output location has not been configured but this seems a misleading error message considering how we fixed it, See also https://github.com/aws/aws-cdk/issues/957

I have the same issue now again with version 1.63 😦

unable to determine cloud assembly output directory. Assets must be defined indirectly within a "Stage" or an "App" scope
Subprocess exited with error 1

Just nuked the node_modules folder, alas. Downgrading everything to “1.6.2” worked. Weird.

There may at least two separate situations which trigger this error: The first case is one where there is a simple discrepancy in the aws cdk version libraries. This can be as subtle as having a package.json with the following entries

    "@aws-cdk/aws-lambda": "^1.60.0",
    "@aws-cdk/core": "1.60.0",

especially after a new version has come out.

If your problem is solved by changing the package.json & setting the cdk libraries to have the exact same version (either all pinned or not) – and updating the package.lock.json-- then it seems to me that the error message is misleading when it says that “Assets must be defined indirectly within a “Stage” or an “App” scope

The second case is one where there is some nesting of the assets (like a lambda). And here the error message kind of makes sense, and is unlikely to be solved by updating the aws cdk package versions.

I got the same error message with 1.57.0 when trying to deploy a NodejsFunction with TypeScript in it. I couldn’t figure out how to configure AWS CDK to make it work.

While trying to figure it out, I removed tsconfig.json and package.json from my Lambda function directory and got some weird permission errors about not being able to create .parcel-cache. At some point .parcel-cache was created as owned by root. Not sure if these problems are caused because I run AWS CDK itself in a Docker container. The asset implementation doesn’t seem to be entirely mature yet.

I’m hoping the NodejsFunction construct will have clear documentation about everything that is needed to make it work.

Just for sanity: can you please nuke your node_modules directory, verify that all the CDK modules in your package.json use the exact same version (preferably pinned), reinstall (yarn install or npm install) and let us know if this persists?