Common Issues
This page lists common issues and their solutions when working with MBC CQRS Serverless applications.
Installation & Setup
npm install fails with peer dependency errors
Symptom: npm install fails with peer dependency warnings or errors.
Solution:
# Use --legacy-peer-deps flag
npm install --legacy-peer-deps
# Or update npm to latest version
npm install -g npm@latest
npm install fails with node-waf error
Symptom: npm install fails with node-waf: command not found error, typically from the zlib package.
npm error path node_modules/zlib
npm error command sh -c node-waf clean || true; node-waf configure build
npm error sh: node-waf: command not found
Cause: Some legacy serverless-offline plugins depend on packages that use the deprecated node-waf build tool.
Solution:
# Skip build scripts during installation
npm install --legacy-peer-deps --ignore-scripts
# Then run postinstall scripts manually
npx prisma generate
CLI command not found
Symptom: mbc-cqrs command is not recognized.
Solution:
# Install globally
npm install -g @mbc-cqrs-serverless/cli
# Or use npx
npx @mbc-cqrs-serverless/cli new my-app
Docker services fail to start
Symptom: docker-compose up fails or services don't start.
Solution:
# Check Docker is running
docker info
# Clean up and restart
docker-compose -f infra-local/docker-compose.yml down -v
docker-compose -f infra-local/docker-compose.yml up -d
# Check logs for specific service
docker-compose -f infra-local/docker-compose.yml logs dynamodb-local
Database Issues
DynamoDB connection refused
Symptom: Cannot connect to DynamoDB Local.
Solution:
- Verify DynamoDB Local is running:
docker ps | grep dynamodb
- Check the endpoint URL in your configuration:
// Should be http://localhost:8000 for local development
dynamodbEndpoint: 'http://localhost:8000'
- Verify tables exist:
aws dynamodb list-tables --endpoint-url http://localhost:8000
Prisma migration errors
Symptom: Prisma migrate fails with connection errors.
Solution:
- Verify PostgreSQL is running:
docker ps | grep postgres
- Check DATABASE_URL in .env:
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/myapp?schema=public"
- Reset and re-run migrations:
npx prisma migrate reset
npx prisma migrate dev
Master API returns 500 Internal Server Error
Symptom: Master API endpoints (/api/master-setting/list, /api/master-data/list) return 500 Internal Server Error.
Cause: The Master module requires both DynamoDB tables and an RDS table. If the masters table doesn't exist in RDS, the API will fail with a 500 error.
Solution:
- Verify the
masterstable exists in RDS:
# For MySQL
docker exec mysql mysql -u root -proot mydb -e "SHOW TABLES LIKE 'masters';"
# For PostgreSQL
docker exec postgres psql -U postgres -d mydb -c "\dt masters"
- If the table is missing, add it to your Prisma schema:
model Master {
pk String @db.VarChar(256)
sk String @db.VarChar(512)
id String @id @db.VarChar(256)
name String @db.VarChar(256)
code String @db.VarChar(256)
version Int @default(0)
tenantCode String @map("tenant_code") @db.VarChar(64)
type String @db.VarChar(256)
attributes Json?
isDeleted Boolean @default(false) @map("is_deleted")
createdAt DateTime @default(now()) @map("created_at")
createdBy String @default("system") @map("created_by") @db.VarChar(256)
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
updatedBy String @default("system") @map("updated_by") @db.VarChar(256)
@@unique([pk, sk])
@@index([tenantCode])
@@map("masters")
}
- Run Prisma migration:
npx prisma migrate dev --name add_master_table
- Verify the DynamoDB tables also exist:
aws dynamodb list-tables --endpoint-url http://localhost:8000 | grep master
# Should show: master-command, master-data, master-history
Serverless Offline fails with missing import_tmp stream
Symptom: npm run offline:sls fails because the LOCAL_DDB_IMPORT_TMP_STREAM environment variable is not set.
Cause: The import_tmp.json table definition file is missing from prisma/dynamodbs/. Without it, npm run migrate cannot create the import_tmp DynamoDB table, so the stream ARN is never written to .env.
In versions prior to v1.1.1, the import_tmp.json template was not included in CLI scaffolded projects. This was fixed in version 1.1.1.
Solution:
Create prisma/dynamodbs/import_tmp.json with the following content:
{
"TableName": "import_tmp",
"AttributeDefinitions": [
{ "AttributeName": "pk", "AttributeType": "S" },
{ "AttributeName": "sk", "AttributeType": "S" }
],
"KeySchema": [
{ "AttributeName": "pk", "KeyType": "HASH" },
{ "AttributeName": "sk", "KeyType": "RANGE" }
],
"BillingMode": "PAY_PER_REQUEST",
"StreamSpecification": {
"StreamEnabled": true,
"StreamViewType": "NEW_IMAGE"
},
"TableClass": "STANDARD",
"DeletionProtectionEnabled": true
}
Then re-run the migration:
npm run migrate
The migration script will automatically create the table and add the LOCAL_DDB_IMPORT_TMP_STREAM entry to your .env file.
DynamoDB throughput exceeded
Symptom: ProvisionedThroughputExceededException error.
Solution:
- For development: Use on-demand billing mode
- For production: Increase provisioned capacity or enable auto-scaling
// CDK configuration for on-demand
const table = new dynamodb.Table(this, 'Table', {
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
});
Lambda Errors
Lambda timeout
Symptom: Task timed out after X seconds.
Solution:
- Increase timeout in CDK:
const handler = new lambda.Function(this, 'Handler', {
timeout: cdk.Duration.seconds(30),
});
- Optimize cold start:
- Reduce bundle size
- Use provisioned concurrency for critical functions
- Move initialization outside handler
Lambda out of memory
Symptom: Runtime.ExitError or memory limit exceeded.
Solution:
const handler = new lambda.Function(this, 'Handler', {
memorySize: 1024, // Increase memory
});
Module not found in Lambda
Symptom: Cannot find module 'xxx' error.
Solution:
- Check bundling configuration:
// Ensure dependencies are bundled
const handler = new lambda_nodejs.NodejsFunction(this, 'Handler', {
bundling: {
externalModules: [], // Don't exclude anything
},
});
- Verify package.json dependencies are correct
Authentication Errors
Cognito token invalid
Symptom: 401 Unauthorized or token validation fails.
Solution:
- Verify Cognito configuration:
// Check USER_POOL_ID and CLIENT_ID match
COGNITO_USER_POOL_ID=ap-northeast-1_xxxxxx
COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
- Check token expiration:
- Access tokens expire after 1 hour by default
- Implement token refresh logic
- Verify issuer URL:
const issuer = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`;
CORS errors
Symptom: Access-Control-Allow-Origin error in browser.
Solution:
- Configure CORS in API Gateway:
const api = new apigateway.HttpApi(this, 'Api', {
corsPreflight: {
allowOrigins: ['http://localhost:3000', 'https://your-domain.com'],
allowMethods: [apigateway.CorsHttpMethod.ANY],
allowHeaders: ['Authorization', 'Content-Type'],
},
});
- Ensure OPTIONS requests are handled
Event Processing
Events not being processed
Symptom: DynamoDB streams or SQS messages not triggering handlers.
Solution:
- Check event source mapping:
aws lambda list-event-source-mappings --function-name your-function
- Verify handler is registered:
@EventHandler(YourEvent)
export class YourEventHandler implements IEventHandler<YourEvent> {
async execute(event: YourEvent): Promise<void> {
// Handler implementation
}
}
- Check CloudWatch Logs for errors
Duplicate event processing
Symptom: Same event processed multiple times.
Solution:
- Implement idempotency:
// Use a unique identifier to check if already processed
// For commands, use pk + sk + version as the idempotency key
const idempotencyKey = `${command.pk}#${command.sk}@${command.version}`;
if (await this.isProcessed(idempotencyKey)) {
return; // Skip duplicate
}
- Configure SQS visibility timeout appropriately
Step Functions
Step Function execution failed
Symptom: State machine execution fails with error.
Solution:
-
Check execution history in AWS Console:
- Go to Step Functions → State machines → Your machine
- Click on failed execution
- Review error details in each step
-
Add error handling:
// Add retry and catch in state machine definition
{
"Retry": [
{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"Catch": [
{
"ErrorEquals": ["States.ALL"],
"Next": "HandleError"
}
]
}
Step Function timeout
Symptom: Execution times out.
Solution:
- Increase timeout in state machine definition
- Break long-running tasks into smaller steps
- Use wait states with callbacks for async operations
Deployment Issues
CDK deployment fails
Symptom: cdk deploy fails with CloudFormation error.
Solution:
- Check CloudFormation events:
aws cloudformation describe-stack-events --stack-name YourStack
-
Common causes:
- IAM permission issues
- Resource limit exceeded
- Invalid resource configuration
-
Roll back and fix:
aws cloudformation delete-stack --stack-name YourStack
# Fix the issue and redeploy
cdk deploy
Resource already exists
Symptom: Resource with name X already exists.
Solution:
- Use unique naming:
const bucket = new s3.Bucket(this, 'Bucket', {
bucketName: `${props.appName}-${props.envName}-${cdk.Aws.ACCOUNT_ID}`,
});
- Or let CDK generate names by not specifying bucketName
Performance Issues
Slow API response times
Symptom: API responses take too long.
Solution:
- Enable Lambda provisioned concurrency
- Implement caching with API Gateway or DAX
- Optimize database queries
- Use connection pooling for RDS
High Lambda costs
Symptom: Unexpectedly high Lambda billing.
Solution:
- Review invocation counts and duration
- Optimize memory allocation (more memory = faster execution)
- Implement request batching
- Use reserved concurrency to limit scaling
Getting Help
If you can't find a solution here:
- Check the Debugging Guide for investigation techniques
- Search existing issues on GitHub
- Create a new issue with:
- Clear description of the problem
- Steps to reproduce
- Error messages and logs
- Environment details (Node version, OS, etc.)