Amplify Gen2 Deployment Issues with Pipeline Resolvers and PostcardAccess System

0

Project Goal and Architecture

We're building a scheduled messaging system with the following features:

Users create postcards with scheduled delivery dates At the scheduled time, the system sends emails with unique access tokens Recipients access postcards via tokens with validation for time limits and view counts Core components are DynamoDB (storage), EventBridge (scheduling), SES (email delivery)

Technical Implementation Challenges We've attempted to implement this using Amplify Gen2 TypeScript CDK approach and encountered multiple persistent errors that prevent deployment despite numerous refactoring attempts.

Implementation 1: Pipeline Resolvers

Our initial approach used pipeline resolvers to:

  1. Create a message in DynamoDB
  2. Schedule delivery with EventBridge Scheduler through an HTTP data source

Error: Consistently failed with The code contains one or more errors for all resolver files, without specific details on what errors exist:

Resource handler returned message: "The code contains one or more errors. (Service: AppSync, Status Code: 400,)

Implementation 2: Simplified JavaScript Resolvers

We simplified all resolver JavaScript files to use only basic syntax:

  • Removed ES6+ features
  • Used explicit variable declarations
  • Added proper semicolons
  • Used traditional if-statements
  • Avoided template literals, arrow functions, destructuring

Error: Still receiving The code contains one or more errors despite extensive simplification.

Implementation 3: Lambda Function Approach

We refactored to use a Lambda function to handle message creation and scheduling:

  1. Created a Lambda function in the Amplify project
  2. Connected it to the GraphQL schema
  3. Added proper IAM roles and permissions

Errors: 1. Encountered circular dependency between stacks: The CloudFormation deployment failed due to circular dependency found between nested stacks [data7552DF31, function1351588B]

2. When using resourceGroupName to place function in data stack: Resource already exists: arn:aws:appsync:us-east-2:<Account_ID>:apis/<unique_data_ID>/types/Mutation/resolvers/createMessageSchedule

Key Issues Encountered

  1. Opaque Error Messages: Errors like "The code contains one or more errors" provide no useful debugging information
  2. Undocumented Resolver Limitations: There appears to be syntax/feature limitations in AppSync resolvers that aren't documented
  3. Stack Organization Challenges: Circular dependencies between data and function stacks are difficult to resolve properly
  4. Resource Naming Collisions: Challenges with existing resources when trying different implementation approaches
  5. Pipeline Resolver Issues: Particularly with HTTP data sources for EventBridge integration
  6. Limited Debugging Capabilities: No way to test resolver code before deployment

Questions for AWS Team

  1. What specific JavaScript syntax/features are supported in AppSync resolvers for Amplify Gen2?
  2. Is there a reliable way to get detailed error information when AppSync returns "The code contains one or more errors"?
  3. Are there known limitations when using HTTP data sources with EventBridge Scheduler in pipeline resolvers?
  4. What is the recommended pattern for implementing scheduled operations (like our email delivery system) in Amplify Gen2?
  5. How can we properly manage circular dependencies between functions and data resources?

Amplify folder node packages: @aws-amplify/backend-cli@1.5.0 @aws-amplify/backend-data@1.5.0 @aws-amplify/backend-function@1.13.0 @aws-amplify/backend-storage@1.3.0 @aws-amplify/backend@1.15.0 @aws-sdk/client-dynamodb@3.788.0 @aws-sdk/client-scheduler@3.787.0 @aws-sdk/client-sesv2@3.787.0 @aws-sdk/client-sso-oidc@3.787.0 @aws-sdk/lib-dynamodb@3.789.0 @aws-sdk/token-providers@3.787.0 @types/aws-lambda@8.10.149 @types/node@22.14.1 aws-cdk-lib@2.190.0 typescript@5.8.3

Next.js folder node packages: @aws-amplify/adapter-nextjs 1.6.0
@aws-amplify/pubsub 6.1.53
@aws-amplify/api 6.3.9
@aws-amplify/ui-react 6.11.0 @aws-amplify/api-graphql 4.7.13
@aws-amplify/ui-react-storage 3.10.0 @aws-amplify/backend 1.14.1
@aws-appsync/utils 1.12.0 @aws-amplify/backend-auth 1.5.1
@aws-sdk/client-dynamodb 3.788.0 @aws-amplify/backend-cli 1.5.0
@aws-sdk/client-ses 3.787.0 @aws-amplify/backend-data 1.4.1
@aws-sdk/client-sesv2 3.787.0 @aws-amplify/backend-function 1.12.3
@aws-sdk/client-sso-oidc 3.787.0 @aws-amplify/backend-storage 1.2.6
@aws-sdk/token-providers 3.787.0 @aws-amplify/data-construct 1.14.8 @aws-amplify/datastore 5.0.80
backend@1.14.1 link:aws-amplify/backend@1.14.1
class-variance-authority 0.7.1
clsx 2.1.1
cmdk 1.1.1
date-fns 4.1.0 date-fns-tz 3.2.0
embla-carousel-react 8.6.0
framer-motion 11.18.2
inherits 2.0.4
lucide-react 0.469.0
luxon 3.6.1 js-cookie 3.0.5
@jest/globals 29.7.0
@radix-ui/react-dialog 1.1.10 @radix-ui/react-dropdown-menu 2.1.10 @radix-ui/react-label 2.1.4 @radix-ui/react-progress 1.1.4 @radix-ui/react-popover 1.1.10 @radix-ui/react-separator 1.1.4 @radix-ui/react-slider 1.3.2 @radix-ui/react-slot 1.2.0 @radix-ui/react-tabs 1.1.7 @radix-ui/react-toast 1.2.10 @radix-ui/react-alert-dialog 1.1.10 @rive-app/react-canvas 4.18.8 react 18.3.1 react-day-picker 9.6.7 react-dom 18.3.1 react-error-boundary 5.0.0 react-hotkeys-hook 4.6.2 react-intersection-observer 9.16.0 next 15.3.1 next-themes 0.4.6 @stripe/stripe-js 5.10.0 @stripe/react-stripe-js 3.6.0 stripe 17.7.0 @tanstack/react-query 5.74.4 @types/js-cookie 3.0.6
@types/luxon 3.6.2
@use-gesture/react 10.3.1
zod 3.24.3

devDependencies: autoprefixer 10.4.21
@babel/core 7.26.10 @babel/plugin-transform-class-properties 7.25.9
@babel/plugin-transform-object-rest-spread 7.25.9
constructs 10.4.2
dotenv 16.5.0
file-loader 6.2.0
eslint-config-next 15.3.1
esbuild 0.23.1
eslint 8.57.1
postcss 8.5.3
tailwindcss 3.4.17 tailwind-merge 3.2.0
tailwindcss-animate 1.0.7 @tanstack/react-query-devtools 5.74.4
@types/react-dom 19.1.2
@types/node 20.11.19 @types/react 19.1.2
@types/jest 29.5.14
@typescript-eslint/parser 6.21.0
@types/aws-lambda 8.10.149
@typescript-eslint/eslint-plugin 6.21.0
typescript 5.8.3
tsx 4.19.3
url-loader 4.1.1 cookies-next 5.1.0

Despite multiple approaches and extensive refactoring, we've been unable to deploy this architecture. Any guidance or examples of working implementations would be greatly appreciated.

1 Answer
0

Thank you for providing such a detailed description of your project and the challenges you're facing with AWS Amplify Gen2. I'll address your questions and provide some guidance based on the information available.

  1. JavaScript syntax in AppSync resolvers for Amplify Gen2: AppSync resolvers in Amplify Gen2 support a subset of JavaScript features. While the exact limitations aren't explicitly documented, it's generally safe to use ES5 syntax. This includes traditional function declarations, var for variables, and avoiding arrow functions, template literals, or destructuring. It's best to stick to basic JavaScript constructs to ensure compatibility.

  2. Detailed error information for AppSync: Unfortunately, the "The code contains one or more errors" message is often not very informative. To get more detailed error information, you can try the following:

  • Use the AWS AppSync console to test your resolvers directly
  • Enable logging for your AppSync API and check CloudWatch logs
  • Use the AWS CLI to describe your resolver and look for specific error messages
  1. HTTP data sources with EventBridge Scheduler in pipeline resolvers: There are no known specific limitations for using HTTP data sources with EventBridge Scheduler in pipeline resolvers. However, ensure that your IAM permissions are correctly set up to allow AppSync to interact with EventBridge.

  2. Recommended pattern for implementing scheduled operations in Amplify Gen2: For scheduled operations like your email delivery system, a combination of AWS Lambda and EventBridge is often the most flexible and reliable approach. You can:

  • Create a Lambda function to handle the email sending logic
  • Use EventBridge rules to trigger the Lambda function on schedule
  • Store the schedule information in DynamoDB
  • Use AppSync to create and manage the schedules, which then updates DynamoDB and creates/updates EventBridge rules
  1. Managing circular dependencies between functions and data resources: To resolve circular dependencies, consider the following:
  • Separate your resources into different stacks (e.g., data stack, function stack)
  • Use the @aws-amplify/backend-output package to share information between stacks
  • Ensure that your function stack depends on your data stack, not vice versa
  • Use the resourceGroupName property to explicitly place resources in the correct stack

Additional recommendations:

  • Simplify your resolver logic as much as possible for initial deployment
  • Use the Amplify CLI to generate basic resolver templates and build upon them
  • Ensure all necessary IAM permissions are correctly set up for your Lambda functions and AppSync API
  • Double-check that your GraphQL schema is correctly defined and matches your resolver implementations
  • Consider using AWS CDK directly for more complex setups that may be challenging to implement with Amplify Gen2

Remember that Amplify Gen2 is still relatively new, and some advanced use cases might require workarounds or alternative implementations. If you continue to face issues, consider reaching out to AWS support or the Amplify community forums for more specific assistance.
Sources
Concepts - AWS Amplify Gen 2 Documentation
Troubleshoot "Stack CDKToolkit already exists" - React - AWS Amplify Gen 2 Documentation
Example pipeline resolver with Amazon DynamoDB - AWS AppSync

profile picture
answered a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions