Closed FirstSanny closed 6 months ago
Hey @FirstSanny, thank you for reaching. I was able to reproduce the issue. The issue appears when creating a project with name that contains -
. for example: test - functions
Unable to build Amplify backend. Check your backend definition in the `amplify` folder.
Caused By: Bundling asset amplify-testfunctions-ykethan-sandbox-15a85b5ebd/function/handler-lambda/Code/Stage...
✘ [ERROR] Invalid build flag: "-"
1 error
/Users/ykethan/Documents/amplifygen2/test - functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:2
`),localBundling=options.local?.tryBundle(bundleDir,options),!localBundling){const assetStagingOptions={sourcePath:this.sourcePath,bundleDir,...options};switch(options.bundlingFileAccess){case bundling_1().BundlingFileAccess.VOLUME_COPY:new(asset_staging_1()).AssetBundlingVolumeCopy(assetStagingOptions).run();break;case bundling_1().BundlingFileAccess.BIND_MOUNT:default:new(asset_staging_1()).AssetBundlingBindMount(assetStagingOptions).run();break}}}catch(err){const bundleErrorDir=bundleDir+"-error";throw fs().existsSync(bundleErrorDir)&&fs().removeSync(bundleErrorDir),fs().renameSync(bundleDir,bundleErrorDir),new Error(`Failed to bundle asset ${this.node.path}, bundle output is located at ${bundleErrorDir}: ${err}`)}if(fs_1().FileSystem.isEmpty(bundleDir)){const outputDir=localBundling?bundleDir:AssetStaging.BUNDLING_OUTPUT_DIR;throw new Error(`Bundling did not produce any output. Check that content is written to ${outputDir}.`)}}calculateHash(hashType,bundling,outputDir){if(hashType==assets_1().AssetHashType.CUSTOM||hashType==assets_1().AssetHashType.SOURCE&&bundling){const hash=crypto().createHash("sha256");return hash.update(this.customSourceFingerprint??fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions)),bundling&&hash.update(JSON.stringify(bundling,sanitizeHashValue)),hash.digest("hex")}switch(hashType){case assets_1().AssetHashType.SOURCE:return fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions);case assets_1().AssetHashType.BUNDLE:case assets_1().AssetHashType.OUTPUT:if(!outputDir)throw new Error(`Cannot use \`${hashType}\` hash type when \`bundling\` is not specified.`);return fs_1().FileSystem.fingerprint(outputDir,this.fingerprintOptions);default:throw new Error("Unknown asset hash type.")}}}exports.AssetStaging=AssetStaging,_a=JSII_RTTI_SYMBOL_1,AssetStaging[_a]={fqn:"aws-cdk-lib.AssetStaging",version:"2.127.0"},AssetStaging.BUNDLING_INPUT_DIR="/asset-input",AssetStaging.BUNDLING_OUTPUT_DIR="/asset-output",AssetStaging.assetCache=new(cache_1()).Cache;function renderAssetFilename(assetHash,extension=""){return`asset.${assetHash}${extension}`}function determineHashType(assetHashType,customSourceFingerprint){const hashType=customSourceFingerprint?assetHashType??assets_1().AssetHashType.CUSTOM:assetHashType??assets_1().AssetHashType.SOURCE;if(customSourceFingerprint&&hashType!==assets_1().AssetHashType.CUSTOM)throw new Error(`Cannot specify \`${assetHashType}\` for \`assetHashType\` when \`assetHash\` is specified. Use \`CUSTOM\` or leave \`undefined\`.`);if(hashType===assets_1().AssetHashType.CUSTOM&&!customSourceFingerprint)throw new Error("`assetHash` must be specified when `assetHashType` is set to `AssetHashType.CUSTOM`.");return hashType}function calculateCacheKey(props){return crypto().createHash("sha256").update(JSON.stringify(sortObject(props),sanitizeHashValue)).digest("hex")}function sortObject(object){if(typeof object!="object"||object instanceof Array)return object;const ret={};for(const key of Object.keys(object).sort())ret[key]=sortObject(object[key]);return ret}function sanitizeHashValue(key,value){if(key==="PIP_INDEX_URL"||key==="PIP_EXTRA_INDEX_URL")try{let url=new URL(value);if(url.password)return url.password="",url.toString()}catch(e){throw e.name==="TypeError"?new Error(`${key} must be a valid URL, got ${value}.`):e}return value}function findSingleFile(directory,archiveOnly){if(!fs().existsSync(directory))throw new Error(`Directory ${directory} does not exist.`);if(!fs().statSync(directory).isDirectory())throw new Error(`${directory} is not a directory.`);const content=fs().readdirSync(directory);if(content.length===1){const file=path().join(directory,content[0]),extension=getExtension(content[0]).toLowerCase();if(fs().statSync(file).isFile()&&(!archiveOnly||ARCHIVE_EXTENSIONS.includes(extension)))return file}}function determineBundledAsset(bundleDir,outputType){const archiveFile=findSingleFile(bundleDir,outputType!==bundling_1().BundlingOutput.SINGLE_FILE);switch(outputType===bundling_1().BundlingOutput.AUTO_DISCOVER&&(outputType=archiveFile?bundling_1().BundlingOutput.ARCHIVED:bundling_1().BundlingOutput.NOT_ARCHIVED),outputType){case bundling_1().BundlingOutput.NOT_ARCHIVED:return{path:bundleDir,packaging:assets_1().FileAssetPackaging.ZIP_DIRECTORY};case bundling_1().BundlingOutput.ARCHIVED:case bundling_1().BundlingOutput.SINGLE_FILE:if(!archiveFile)throw new Error("Bundling output directory is expected to include only a single file when `output` is set to `ARCHIVED` or `SINGLE_FILE`");return{path:archiveFile,packaging:assets_1().FileAssetPackaging.FILE,extension:getExtension(archiveFile)}}}function getExtension(source){for(const ext of ARCHIVE_EXTENSIONS)if(source.toLowerCase().endsWith(ext))return ext;return path().extname(source)}
^
note: creating a project folder name as test functions
Unable to build Amplify backend. Check your backend definition in the `amplify` folder.
Caused By: Bundling asset amplify-testfunctions-ykethan-sandbox-15a85b5ebd/function/handler-lambda/Code/Stage...
✘ [ERROR] Must use "outdir" when there are multiple input files
1 error
/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:2
`),localBundling=options.local?.tryBundle(bundleDir,options),!localBundling){const assetStagingOptions={sourcePath:this.sourcePath,bundleDir,...options};switch(options.bundlingFileAccess){case bundling_1().BundlingFileAccess.VOLUME_COPY:new(asset_staging_1()).AssetBundlingVolumeCopy(assetStagingOptions).run();break;case bundling_1().BundlingFileAccess.BIND_MOUNT:default:new(asset_staging_1()).AssetBundlingBindMount(assetStagingOptions).run();break}}}catch(err){const bundleErrorDir=bundleDir+"-error";throw fs().existsSync(bundleErrorDir)&&fs().removeSync(bundleErrorDir),fs().renameSync(bundleDir,bundleErrorDir),new Error(`Failed to bundle asset ${this.node.path}, bundle output is located at ${bundleErrorDir}: ${err}`)}if(fs_1().FileSystem.isEmpty(bundleDir)){const outputDir=localBundling?bundleDir:AssetStaging.BUNDLING_OUTPUT_DIR;throw new Error(`Bundling did not produce any output. Check that content is written to ${outputDir}.`)}}calculateHash(hashType,bundling,outputDir){if(hashType==assets_1().AssetHashType.CUSTOM||hashType==assets_1().AssetHashType.SOURCE&&bundling){const hash=crypto().createHash("sha256");return hash.update(this.customSourceFingerprint??fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions)),bundling&&hash.update(JSON.stringify(bundling,sanitizeHashValue)),hash.digest("hex")}switch(hashType){case assets_1().AssetHashType.SOURCE:return fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions);case assets_1().AssetHashType.BUNDLE:case assets_1().AssetHashType.OUTPUT:if(!outputDir)throw new Error(`Cannot use \`${hashType}\` hash type when \`bundling\` is not specified.`);return fs_1().FileSystem.fingerprint(outputDir,this.fingerprintOptions);default:throw new Error("Unknown asset hash type.")}}}exports.AssetStaging=AssetStaging,_a=JSII_RTTI_SYMBOL_1,AssetStaging[_a]={fqn:"aws-cdk-lib.AssetStaging",version:"2.127.0"},AssetStaging.BUNDLING_INPUT_DIR="/asset-input",AssetStaging.BUNDLING_OUTPUT_DIR="/asset-output",AssetStaging.assetCache=new(cache_1()).Cache;function renderAssetFilename(assetHash,extension=""){return`asset.${assetHash}${extension}`}function determineHashType(assetHashType,customSourceFingerprint){const hashType=customSourceFingerprint?assetHashType??assets_1().AssetHashType.CUSTOM:assetHashType??assets_1().AssetHashType.SOURCE;if(customSourceFingerprint&&hashType!==assets_1().AssetHashType.CUSTOM)throw new Error(`Cannot specify \`${assetHashType}\` for \`assetHashType\` when \`assetHash\` is specified. Use \`CUSTOM\` or leave \`undefined\`.`);if(hashType===assets_1().AssetHashType.CUSTOM&&!customSourceFingerprint)throw new Error("`assetHash` must be specified when `assetHashType` is set to `AssetHashType.CUSTOM`.");return hashType}function calculateCacheKey(props){return crypto().createHash("sha256").update(JSON.stringify(sortObject(props),sanitizeHashValue)).digest("hex")}function sortObject(object){if(typeof object!="object"||object instanceof Array)return object;const ret={};for(const key of Object.keys(object).sort())ret[key]=sortObject(object[key]);return ret}function sanitizeHashValue(key,value){if(key==="PIP_INDEX_URL"||key==="PIP_EXTRA_INDEX_URL")try{let url=new URL(value);if(url.password)return url.password="",url.toString()}catch(e){throw e.name==="TypeError"?new Error(`${key} must be a valid URL, got ${value}.`):e}return value}function findSingleFile(directory,archiveOnly){if(!fs().existsSync(directory))throw new Error(`Directory ${directory} does not exist.`);if(!fs().statSync(directory).isDirectory())throw new Error(`${directory} is not a directory.`);const content=fs().readdirSync(directory);if(content.length===1){const file=path().join(directory,content[0]),extension=getExtension(content[0]).toLowerCase();if(fs().statSync(file).isFile()&&(!archiveOnly||ARCHIVE_EXTENSIONS.includes(extension)))return file}}function determineBundledAsset(bundleDir,outputType){const archiveFile=findSingleFile(bundleDir,outputType!==bundling_1().BundlingOutput.SINGLE_FILE);switch(outputType===bundling_1().BundlingOutput.AUTO_DISCOVER&&(outputType=archiveFile?bundling_1().BundlingOutput.ARCHIVED:bundling_1().BundlingOutput.NOT_ARCHIVED),outputType){case bundling_1().BundlingOutput.NOT_ARCHIVED:return{path:bundleDir,packaging:assets_1().FileAssetPackaging.ZIP_DIRECTORY};case bundling_1().BundlingOutput.ARCHIVED:case bundling_1().BundlingOutput.SINGLE_FILE:if(!archiveFile)throw new Error("Bundling output directory is expected to include only a single file when `output` is set to `ARCHIVED` or `SINGLE_FILE`");return{path:archiveFile,packaging:assets_1().FileAssetPackaging.FILE,extension:getExtension(archiveFile)}}}function getExtension(source){for(const ext of ARCHIVE_EXTENSIONS)if(source.toLowerCase().endsWith(ext))return ext;return path().extname(source)}
^
Error: Failed to bundle asset amplify-testfunctions-ykethan-sandbox-15a85b5ebd/function/handler-lambda/Code/Stage, bundle output is located at /Users/ykethan/Documents/amplifygen2/test functions/.amplify/artifacts/cdk.out/bundling-temp-3397b059429bbdc75650432164573505d97bfe968ff18a4a643e6f0008c8fb20-error: Error: bash -c npx --no-install esbuild --bundle "/Users/ykethan/Documents/amplifygen2/test functions/amplify/function/handler.ts" --target=node18 --platform=node --format=esm --outfile="/Users/ykethan/Documents/amplifygen2/test functions/.amplify/artifacts/cdk.out/bundling-temp-3397b059429bbdc75650432164573505d97bfe968ff18a4a643e6f0008c8fb20/index.mjs" --external:@aws-sdk/* --banner:js="/** * This code loads environment values from SSM and places them in their corresponding environment variables. * If there are no SSM environment values for this function, this is a noop. */import { SSM } from '@aws-sdk/client-ssm';/** * Reads SSM environment context from a known Amplify environment variable, * fetches values from SSM and places those values in the corresponding environment variables */export const internalAmplifyFunctionResolveSsmParams = async (client = new SSM()) => { const envPathObject = JSON.parse(process.env.AMPLIFY_SSM_ENV_CONFIG ?? '{}'); const paths = Object.keys(envPathObject); if (paths.length === 0) { return; } const resolveSecrets = async (paths) => { const response = await client.getParameters({ Names: paths, WithDecryption: true, }); if (response.Parameters && response.Parameters.length > 0) { for (const parameter of response.Parameters) { if (parameter.Name) { const envKey = Object.keys(envPathObject).find((key) => envPathObject[key].sharedPath === parameter.Name); const envName = envKey ? envPathObject[envKey].name : envPathObject[parameter.Name]?.name; process.env[envName] = parameter.Value; } } } return response; }; const response = await resolveSecrets(paths); const sharedPaths = (response?.InvalidParameters || []) .map((invalidParam) => envPathObject[invalidParam].sharedPath) .filter((sharedParam) => !!sharedParam); if (sharedPaths.length > 0) { await resolveSecrets(sharedPaths); }};await internalAmplifyFunctionResolveSsmParams();const SSM_PARAMETER_REFRESH_MS = 1000 * 60;setInterval(() => { void internalAmplifyFunctionResolveSsmParams();}, SSM_PARAMETER_REFRESH_MS);export {};" --inject:/Users/ykethan/Documents/amplifygen2/test functions/node_modules/@aws-amplify/backend-function/lib/lambda-shims/cjs_shim.js run in directory /Users/ykethan/Documents/amplifygen2/test functions exited with status 1
at AssetStaging.bundle (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:2:619)
at AssetStaging.stageByBundling (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:5297)
at stageThisAsset (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2728)
at Cache.obtain (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/private/cache.js:1:242)
at new AssetStaging (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:3125)
at new Asset (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:1080)
at AssetCode.bind (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/aws-lambda/lib/code.js:1:4881)
at new Function (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:9422)
at new NodejsFunction (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:1669)
at AmplifyFunction (/Users/ykethan/Documents/amplifygen2/test functions/node_modules/@aws-amplify/backend-function/src/factory.ts:260:28)
Confirmed that this is an issue with Amplify, CDK works fine.
Moreover the issue is with how shims are generated, as I'm able to build correctly without the shims or with Node16 (which doesn't use Shim)
Based on the error message above, I would expect this to repro even when using NodejsFunction directly in cdk when bundlingOptions.inject has a path that contains spaces: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.BundlingOptions.html
Hello there, sorry for the late reply, but i fell sick... I can confirm, that it works as described after removing all the dashes and spaces from my building path. Thank you very much @ykethan
@ykethan This issue is also if there is a space (or dash?, did not test) in any part of the absolute path, not just the name of the function folder, etc.
This will fail:
~/Some Folder/Gen2Test/amplify/functions/mytest
This should be fixed with this change in aws-cdk: https://github.com/aws/aws-cdk/pull/29561
Environment information
Description
Did follow both guides:
I didnt even touch the code from the examples. It is failing on me with the exact example from the guides. And for both I am getting the same error messages from trying to deploy to sandbox: