Troubleshooting
This guide helps you diagnose and resolve common issues with your Wrist Agent deployment.
Quick Diagnostics
Test Connectivity
# Get your API endpoint
API_ENDPOINT=$(aws cloudformation describe-stacks \
--stack-name WristAgentStack \
--query 'Stacks[0].Outputs[?OutputKey==`InvokeEndpoint`].OutputValue' \
--output text)
# Check if API Gateway is accessible (expect 403 without token)
curl -I "$API_ENDPOINT"
# Expected: HTTP/2 403 (authorization required)
# If timeout or connection refused, check deployment
Verify Authentication
# Get your token
TOKEN=$(aws ssm get-parameter \
--name "/wrist-agent/client-token" \
--with-decryption \
--query 'Parameter.Value' \
--output text)
# Get API endpoint
API_ENDPOINT=$(aws cloudformation describe-stacks \
--stack-name WristAgentStack \
--query 'Stacks[0].Outputs[?OutputKey==`InvokeEndpoint`].OutputValue' \
--output text)
# Test with token
curl -X POST "$API_ENDPOINT" \
-H "Content-Type: application/json" \
-H "X-Client-Token: $TOKEN" \
-d '{"text": "test", "mode": "note"}'
# Expected: JSON response with markdown field
Check Lambda Logs
# View main Lambda logs
aws logs tail /aws/lambda/WristAgentStack-WristAgentHandler --follow
# View authorizer Lambda logs
aws logs tail /aws/lambda/WristAgentStack-WristAgentAuthorizer --follow
# Search for errors in last hour (main handler)
aws logs filter-log-events \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentHandler" \
--start-time $(date -d '1 hour ago' +%s)000 \
--filter-pattern "ERROR"
# Search for authorization denials (authorizer)
aws logs filter-log-events \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentAuthorizer" \
--start-time $(date -d '1 hour ago' +%s)000 \
--filter-pattern "denied"
Common Issues
Authentication Errors
403 Forbidden (API Gateway Authorizer)
Symptoms:
{
"Message": "User is not authorized to access this resource with an explicit deny"
}
Error Types in CloudWatch Logs:
The Lambda Authorizer returns specific error types that can be found in CloudWatch Logs:
| Error Type | Description | Solution |
|---|---|---|
missing_token | X-Client-Token header not provided | Add header to request |
token_mismatch | Token doesn't match SSM parameter value | Update token in shortcut or SSM |
ssm_failure | Failed to retrieve token from SSM | Check Lambda IAM permissions |
Diagnostics with CloudWatch Logs Insights:
# Query authorizer logs for denied requests
aws logs start-query \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentAuthorizer" \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /denied/ | sort @timestamp desc | limit 20'
# Check for SSM failures
aws logs start-query \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentAuthorizer" \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /ssm_failure/ or @message like /failed to get SSM/'
Solutions:
# Verify token in SSM
aws ssm get-parameter \
--name "/wrist-agent/client-token" \
--with-decryption \
--query 'Parameter.Value' \
--output text
# Compare with token in your shortcut
# If different, update shortcut with correct token
# Or generate new token and update both (use SecureString for production)
NEW_TOKEN=$(openssl rand -base64 32)
aws ssm put-parameter \
--name "/wrist-agent/client-token" \
--value "$NEW_TOKEN" \
--type SecureString \
--overwrite
echo "Update your shortcut with: $NEW_TOKEN"
# Clear authorizer cache by redeploying API Gateway
aws apigateway create-deployment \
--rest-api-id $(aws apigateway get-rest-apis --query 'items[?name==`Wrist Agent API`].id' --output text) \
--stage-name prod
API Gateway Rate Limiting (429)
Symptoms:
{
"message": "Rate Exceeded."
}
Causes:
- Too many requests in short period (limit: 10 req/sec, burst: 20)
- Automated scripts hitting API too frequently
Solutions:
- Wait a few seconds and retry
- Implement exponential backoff in client code
- For legitimate high-volume needs, update rate limits in CDK stack
Bedrock Errors
Access Denied to Bedrock Model
Symptoms:
AccessDeniedException: Could not access model
Causes:
- Model access not enabled in Bedrock console
- Wrong region
- Insufficient IAM permissions
Solutions:
# Enable model access (one-time setup)
# 1. Go to AWS Bedrock Console → Model Access
# 2. Request access to "Anthropic Claude Haiku 4.5"
# 3. Wait for approval (usually instant)
# Verify region matches your deployment
aws cloudformation describe-stacks \
--stack-name WristAgentStack \
--query 'Stacks[0].Outputs[?OutputKey==`Region`].OutputValue' \
--output text
# Check Lambda execution role permissions
aws iam get-role-policy \
--role-name WristAgentStack-WristAgentHandlerRole \
--policy-name BedrockAccess
Model Not Found
Symptoms:
ResourceNotFoundException: Model not found
Causes:
- Model ID incorrect or not available in region
- Region doesn't support Claude Haiku 4.5
Solutions:
# List available Bedrock models in your region
aws bedrock list-foundation-models \
--region us-west-2 \
--query 'modelSummaries[?providerName==`Anthropic`]'
# Update to correct model ID in your deployment
# Edit cdk/lib/config.ts or set environment variable
export BEDROCK_MODEL_ID=anthropic.claude-haiku-4-5-20251001-v1:0
Lambda Function Errors
Timeout Errors
Symptoms:
Task timed out after 30.00 seconds
Causes:
- Bedrock response taking too long
- Large thinking token requests
- Network latency
Solutions:
# Increase Lambda timeout
# Edit cdk/lib/config.ts
# timeout: cdk.Duration.seconds(60),
# Then redeploy
cd cdk
npx cdk deploy
# For immediate fix, use AWS Console:
# Lambda → Configuration → General → Timeout → 60 seconds
Out of Memory
Symptoms:
Runtime exited with error: signal: killed
Causes:
- Large response payloads
- Insufficient memory allocation
Solutions:
# Increase Lambda memory
# Edit cdk/lib/config.ts
# memorySize: 512,
# Then redeploy
cd cdk
npx cdk deploy
# Or use console: Lambda → Configuration → General → Memory
Cold Start Issues
Symptoms:
- First request after idle period is slow
- Intermittent timeouts
Solutions:
# Add provisioned concurrency (increases cost)
# In CDK:
# this.fn.currentVersion.addAlias('live', {
# provisionedConcurrentExecutions: 1,
# });
# Or accept cold starts as normal behavior
# Typical cold start: 1-3 seconds
Apple Shortcut Issues
Shortcut Fails Silently
Symptoms:
- Shortcut completes but no output
- No error message shown
Causes:
- Network connectivity issues
- Invalid JSON in request
- Response parsing errors
Solutions:
// In Shortcuts, add "Show Result" action after API call
// to see the raw response
// Add error handling:
// 1. Add "Get Dictionary Value" for "error" key
// 2. If error exists, show notification with error message
// 3. Otherwise, proceed with normal flow
Voice Dictation Accuracy
Symptoms:
- Incorrect transcription
- Missing words or phrases
Solutions:
- Speak clearly with pauses between sentences
- Use punctuation words: "comma", "period", "question mark"
- Enable research mode for better processing of unclear text
- Review and edit text before sending to API
- Use a quieter environment to reduce background noise
Watch Complication Not Appearing
Symptoms:
- Shortcut works on iPhone but not visible on Watch
- Complication slot empty
Solutions:
# On iPhone:
# 1. Open Watch app
# 2. Go to My Watch → Shortcuts
# 3. Verify shortcut is enabled for Watch
# 4. Force sync: Toggle airplane mode on/off
# On Apple Watch:
# 1. Force restart: Hold side button + Digital Crown
# 2. Re-add complication to watch face
Deployment Issues
CDK Bootstrap Failure
Symptoms:
Error: This stack uses assets, so the toolkit stack must be deployed
Solutions:
# Bootstrap CDK in your account/region
npx cdk bootstrap aws://ACCOUNT-ID/REGION
# Or with specific profile
npx cdk bootstrap --profile your-profile
# Verify bootstrap stack exists
aws cloudformation describe-stacks \
--stack-name CDKToolkit
GitHub Actions Deployment Failure
Symptoms:
- Workflow fails with permission errors
- OIDC authentication fails
Solutions:
# Verify OIDC provider exists
aws iam list-open-id-connect-providers
# Check role trust policy
aws iam get-role --role-name WristAgentGitHubActions \
--query 'Role.AssumeRolePolicyDocument'
# Verify GitHub secret is set correctly
# Settings → Secrets → Actions → AWS_ROLE_ARN
# Should be: arn:aws:iam::ACCOUNT-ID:role/WristAgentGitHubActions
Stack Update Failures
Symptoms:
Error: Resource update failed
Solutions:
# Check what's being updated
npx cdk diff
# View CloudFormation events
aws cloudformation describe-stack-events \
--stack-name WristAgentStack \
--query 'StackEvents[0:10]'
# If stuck, rollback and retry
npx cdk deploy --rollback-configuration RollbackTriggers=[]
# Nuclear option: destroy and redeploy
npx cdk destroy
npx cdk deploy
Performance Issues
Slow Response Times
Symptoms:
- Requests taking >10 seconds
- Inconsistent latency
Diagnostics:
# Measure response time
time curl -X POST "$FUNCTION_URL" \
-H "Content-Type: application/json" \
-H "X-Client-Token: $TOKEN" \
-d '{"text": "test", "mode": "note"}'
# Check Lambda duration metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Duration \
--dimensions Name=FunctionName,Value=WristAgentStack-WristAgentHandler \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 300 \
--statistics Average,Maximum
Solutions:
- Reduce token limits in request
- Use faster mode (note vs deepthink)
- Optimize Lambda memory (more memory = faster CPU)
- Check Bedrock service health in your region
High Costs
Symptoms:
- Unexpected AWS bill
- Bedrock charges higher than expected
Solutions:
# Check Bedrock usage
aws ce get-cost-and-usage \
--time-period Start=$(date -d '1 month ago' +%Y-%m-%d),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics BlendedCost \
--filter file://<(echo '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Bedrock"]}}')
# Set up billing alarm
aws cloudwatch put-metric-alarm \
--alarm-name WristAgent-CostAlert \
--alarm-description "Alert when costs exceed $50" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 86400 \
--threshold 50 \
--comparison-operator GreaterThanThreshold
# Optimize usage:
# 1. Reduce maxTokens in requests
# 2. Use thinkingTokens=0 for simple tasks
# 3. Batch multiple items into one request
Debugging Tools
Enable Debug Logging
// In lambda/main.go, add debug output
log.Printf("Request: %+v\n", request)
log.Printf("Response: %+v\n", response)
Monitor with CloudWatch Insights
# Query for errors
aws logs start-query \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentHandler" \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /ERROR/'
# Query for slow requests
aws logs start-query \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentHandler" \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @duration | filter @duration > 5000'
Test Locally
# Build Lambda locally
cd lambda
GOOS=linux GOARCH=arm64 go build -o bootstrap main.go
# Run with AWS SAM (optional)
sam local start-api
# Test with curl
curl -X POST http://localhost:3000/ \
-H "Content-Type: application/json" \
-H "X-Client-Token: test" \
-d '{"text": "test", "mode": "note"}'
Getting Help
Check CloudWatch Logs
Most issues can be diagnosed from Lambda logs:
# Real-time log monitoring
aws logs tail /aws/lambda/WristAgentStack-WristAgentHandler \
--follow \
--format short
# Export logs for analysis
aws logs create-export-task \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentHandler" \
--from $(date -d '1 day ago' +%s)000 \
--to $(date +%s)000 \
--destination wrist-agent-logs \
--destination-prefix troubleshooting
Collect Diagnostic Information
When reporting issues, include:
# System information
echo "AWS Region: $(aws configure get region)"
echo "CDK Version: $(npx cdk --version)"
echo "Go Version: $(go version)"
echo "Node Version: $(node --version)"
# Deployment information
aws cloudformation describe-stacks \
--stack-name WristAgentStack \
--query 'Stacks[0].Outputs'
# Recent errors
aws logs filter-log-events \
--log-group-name "/aws/lambda/WristAgentStack-WristAgentHandler" \
--start-time $(date -d '1 hour ago' +%s)000 \
--filter-pattern "ERROR"
Prevention
Regular Maintenance
# Weekly checks
1. Review CloudWatch metrics for anomalies
2. Check AWS costs in billing dashboard
3. Verify token security (no unauthorized usage)
4. Update dependencies (npm, go modules)
# Monthly tasks
1. Rotate authentication token
2. Review and clean up CloudWatch logs
3. Test backup/recovery procedures
4. Update to latest Bedrock model if available
Monitoring Setup
# Create CloudWatch dashboard
aws cloudwatch put-dashboard \
--dashboard-name WristAgent \
--dashboard-body file://dashboard.json
# Set up SNS topic for alerts
aws sns create-topic --name wrist-agent-alerts
# Subscribe to alerts
aws sns subscribe \
--topic-arn arn:aws:sns:REGION:ACCOUNT:wrist-agent-alerts \
--protocol email \
--notification-endpoint your-email@example.com
Next Steps
- Review Security Best Practices - Prevent security issues
- Optimize Your Deployment - Improve performance
- Explore API Examples - Learn advanced usage