Closed jewells07 closed 1 day ago
Hi @jewells07, the The code contains one or more errors
is a bit difficult to troubleshoot. Can you share a bit more info about the decodeValue
function being imported and what it does?
Where is it being imported from? The @
in the import is a pattern I've seen in JS frameworks like Next/Nuxt and is configurable through a tsconfig
file, but I'm not sure if it will work or apply to the bundling of the Lambda. Maybe try using a relative path rather than an implicit one and move the utility to the same folder as the lambda.
Yes, that util is from outside the amplify folder. and in Nuxt 3 server folder @/server/utils/encodeDecode
i'm using some packages to encode decode some secret values. that file also including
import { parseAmplifyConfig } from 'aws-amplify/utils';
import type { Schema } from '~/amplify/data/resource';
import { generateClient } from 'aws-amplify/api/server';
import outputs from '~/amplify_outputs.json';
const amplifyConfig = parseAmplifyConfig(outputs);
const gqlServerClient = generateClient<Schema>({ config: amplifyConfig });
.....<rest code>
So you mean to say that whatever files are available in the amplify folder that can only be imported, not from outside the amplify folder?
So you mean to say that whatever files are available in the amplify folder that can only be imported, not from outside the amplify folder?
It should be possible to import from outside the amplify folder, but I think only using a relative path. So instead of @/server/utils/encodeDecode
, try a path like ../../server/utils/encodeDecode
. If that doesn't work then colocating the utils in the amplify and/or lambda folder might help. I think the main issue is the @/
part of the path.
import { decodeStatus } from '../../../server/utils/encodeDecodeBookingStatus';
This is also giving me an error.
The CloudFormation deployment has failed.
Caused By: ❌ Deployment failed: BadRequestException: The code contains one or more errors.
Resolution: Find more information in the CloudFormation AWS Console for this stack.
One of the packages I'm using is 'js-base64', and I'm trying to import it import { decode } from 'js-base64';
. This is also giving me the same error.
NOTE
: I have installed js-base64
in my Nuxt, not in the amplify folder. The package.json
in the amplify folder is still empty.
{
"type": "module"
}
I mistook your handler for a Lambda, but you're actually using an AppSync JS resolver.
I dug into this a little and import
is not allowed (outside of @aws-appsync/utils
which is a special package provided by AppSync), all code has to be in the same file for AppSync JS resolvers.
You will have to use esbuild
to bundle the resolver and make sure that it is bundled as ESM modules, as AppSync doesn't support CommonJS.
Here's an example:
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
src/appsync/getPost.resolver.js
For more information, please refer to the AppSync docs:
https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html
Do I need to create everything from scratch, or can I just build what I want to import and then use it for importing? I'm not sure how this process works.
You can write your resolver as js or take file like normal, importing whatever you need into your resolver. Then you would use esbuild to bundle your resolver and everything it depends on into one file.
Try using the example command above and bundle a resolver that imports your utility and check the output.
The last argument of the command is the file(s) you want to bundle.
Here's an example of bundling multiple files from the AppSync docs:
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
src/appsync/**/*.ts
I have created the file using esbuild
in ./amplify/data/Todo/esbuildResolver/createTodo.js
and changed the entry path in custom mutation
CreatingTodo: a
.mutation()
.arguments({
id: a.string(),
title: a.string().required(),
})
.returns(a.ref('Todo'))
.handler([
a.handler.custom({
entry: './Todo/esbuildResolver/createTodo.js',
dataSource: a.ref('Todo'),
}),
])
.authorization((allow) => [allow.authenticated()]),
I encountered the same error again.
The CloudFormation deployment has failed.
Caused By: ❌ Deployment failed: BadRequestException: Code must be 32768 bytes or less
Resolution: Find more information in the CloudFormation AWS Console for this stack.
and however, when I reverted the code and ran esbuild, it worked as it did before.
It looks like you ran into a bundle size limitation. Does your utility import other dependencies?
In any case, even if you reduce the size of the bundle, you will probably still run into compatibility issues with the code you or dependencies are trying to execute.
AppSync JS resolvers are simply meant to tell AppSync how to translate an incoming GraphQL request into an operation for your data source and how to translate the response from that data source back into a GraphQL response.
This being said, if you need to import code that may contain unsupported features like async await, try/catch, etc, then you should consider using a Lambda function as a data source and connect to the database from it instead.
https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html
This part of the AppSync docs explains the use cases and when to choose between JS resolvers and Lambda functions:
It also mentions the maximum size of code being 32,000 characters which seems aligned with the error message.
My utils contain the following code:
import { encode, decode } from 'js-base64';
import { gqlServerClient } from '@/utils/amplifyUtils';
....<rest code>
I also tried removing my utils and simply importing import { decode } from 'js-base64';
in my resolver. but I am still encountering the same error.
Yeah that's an external module from npm, which could be using unsupported js runtime features that AppSync JS resolvers don't support.
Also, the size of that package alone is too large and exceeds the 32,000 byte limit.
I would recommend using a Lambda instead.
Is the issue due to size or unsupported js runtime features? The error details are not visible anywhere, making it very annoying. How can I check the details when this type of error occurs? Do you mean we can use Lambda, or should we write our own code that does not include external packages?
Probably both.
The original error message in the issue description was
Caused By: ❌ Deployment failed: BadRequestException: The code contains one or more errors.
This could be for a lot of reasons, including attempting to use unsupported JS features or even simply syntax errors. It's not a very helpful message. There is a linter that you can use that might help catch these errors before deployment, also mentioned in the AppSync docs.
When you bundled the code to include the js-base64 module in the resolver, the size inflated past the limit, resulting in the second error message:
Caused By: ❌ Deployment failed: BadRequestException: Code must be 32768 bytes or less
I'm suggesting using a Lambda for your resolver instead because it doesn't have the limitations of support for external modules and the bundle size limit is much higher (I think 50MB?)
Yes, I plan to use a Lambda function, but first, I want to try using a JavaScript resolver. I attempted to write the code in simple JavaScript, but even a simple while loop is causing the same error.
Funny enough, while loops are not supported either 😅
https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html
That's wild! 😱🤣 Looks like Lambda is the only option left. 😄
This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.
Amplify CLI Version
12.12.2
Question
Im using (
Nuxt 3 + Amplify gen 2
). I have custom mutation with handler./amplify/data/resource.ts
./amplify/data/Todo/createTodo.js
It keeps giving me an error.
If I remove
import { decodeValue } from @/server/utils/encodeDecode
. then its working fine. but I need thatdecodeValue
util. I checked in CloudFormation, and there was no failed stack. Can someone explain to me how to check the error detail?