aws-amplify / amplify-backend

Home to all tools related to Amplify's code-first DX (Gen 2) for building fullstack apps on AWS
Apache License 2.0
175 stars 60 forks source link

Adding a custom function is failing #1023

Closed FirstSanny closed 6 months ago

FirstSanny commented 8 months ago

Environment information

System:
  OS: Windows 11 10.0.22631
  CPU: (16) x64 AMD Ryzen 7 7700X 8-Core Processor
  Memory: 12.19 GB / 31.12 GB
Binaries:
  Node: 20.6.1 - C:\Program Files\nodejs\node.EXE
  Yarn: undefined - undefined
  npm: 10.2.5 - C:\Program Files\nodejs\npm.CMD
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/backend: 0.12.1
  @aws-amplify/backend-cli: 0.11.1
  aws-amplify: 6.0.16
  aws-cdk: 2.127.0
  aws-cdk-lib: 2.127.0
  typescript: 5.3.3
AWS environment variables:
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
  AWS_STS_REGIONAL_ENDPOINTS = regional
No CDK environment variables

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:

Caused By: Be careful when using @auth directives on a field in a root type. @auth directives on field definitions use the source object to perform authorization logic and the source will be an empty object for fields on root types. Static group authorization should perform as expected.
WARNING: owners may reassign ownership for the following model(s) and role(s): Return: [owner]. If this is not intentional, you may want to apply field-level authorization rules to these fields. To read more: https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access.
Bundling asset amplify-crpamplify-Rebolet-sandbox-ad0c6b7c97/function/order-searcher-lambda/Code/Stage...
X [ERROR] Invalid build flag: "-"

1 error
node:child_process:929
    throw err;
    ^

Error: Command failed: D:\code\VS - Customer Experience\crp-amplify\node_modules\@esbuild\win32-x64\esbuild.exe --bundle D:\code\VS - Customer Experience\crp-amplify\amplify\functions\order-searcher\handler.ts --target=node18 --platform=node --format=esm --outfile=D:\code\VS - Customer Experience\crp-amplify\.amplify\artifacts\cdk.out\bundling-temp-0a784900e152d06132f8d60c1521e65ace872ca11c2d4e3cb3d96e4ab0117df7\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:D:\code\VS - Customer Experience\crp-amplify\node_modules\@aws-amplify\backend-function\lib\lambda-shims\cjs_shim.js
    at checkExecSyncError (node:child_process:890:11)
    at Object.execFileSync (node:child_process:926:15)
    at Object.<anonymous> (D:\code\VS - Customer Experience\crp-amplify\node_modules\esbuild\bin\esbuild:221:28)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
    at node:internal/main/run_main_module:23:47 {
  status: 1,
  signal: null,
  output: [ null, null, null ],
  pid: 28040,
  stdout: null,
  stderr: null
}

Node.js v20.6.1
D:\code\VS - Customer Experience\crp-amplify\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-crpamplify-Rebolet-sandbox-ad0c6b7c97/function/order-searcher-lambda/Code/Stage, bundle output is located at D:\code\VS - Customer Experience\crp-amplify\.amplify\artifacts\cdk.out\bundling-temp-0a784900e152d06132f8d60c1521e65ace872ca11c2d4e3cb3d96e4ab0117df7-error: Error: cmd /c npx.cmd --no-install esbuild --bundle "D:\code\VS - Customer Experience\crp-amplify\amplify\functions\order-searcher\handler.ts" --target=node18 --platform=node --format=esm --outfile="D:\code\VS - Customer Experience\crp-amplify\.amplify\artifacts\cdk.out\bundling-temp-0a784900e152d06132f8d60c1521e65ace872ca11c2d4e3cb3d96e4ab0117df7\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:D:\code\VS - Customer Experience\crp-amplify\node_modules\@aws-amplify\backend-function\lib\lambda-shims\cjs_shim.js run in directory D:\code\VS - Customer Experience\crp-amplify exited with status 1
    at AssetStaging.bundle (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\core\lib\asset-staging.js:2:619)
    at AssetStaging.stageByBundling (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\core\lib\asset-staging.js:1:5297)
    at stageThisAsset (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\core\lib\asset-staging.js:1:2728)
    at Cache.obtain (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\core\lib\private\cache.js:1:242)
    at new AssetStaging (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\core\lib\asset-staging.js:1:3125)
    at new Asset (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\aws-s3-assets\lib\asset.js:1:1080)
    at AssetCode.bind (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\aws-lambda\lib\code.js:1:4881)
    at new Function (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\aws-lambda\lib\function.js:1:9422)
    at new NodejsFunction (D:\code\VS - Customer Experience\crp-amplify\node_modules\aws-cdk-lib\aws-lambda-nodejs\lib\function.js:1:1669)
    at AmplifyFunction (D:\code\VS - Customer Experience\crp-amplify\node_modules\@aws-amplify\backend-function\src\factory.ts:260:28)

Node.js v20.6.1
ykethan commented 8 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)}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ^
ykethan commented 8 months ago

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)
Amplifiyer commented 8 months ago

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)

edwardfoyle commented 8 months ago

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

FirstSanny commented 8 months ago

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

pkubat commented 8 months ago

@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

bombguy commented 6 months ago

This should be fixed with this change in aws-cdk: https://github.com/aws/aws-cdk/pull/29561

bombguy commented 6 months ago

Unable to reproduce with the newest release of aws-cdk & aws-cdk-lib (2.138.0)

Creating a new app or upgrading the CDK version in existing project should fix this issue.