Wraps Logo
DocsHome
Reference

Error Codes & Troubleshooting

Complete reference for all CLI error codes and SDK error classes, with solutions for each.

CLI Error Codes

Credentials & Session

CodeMessageSolution
NO_AWS_CREDENTIALSAWS credentials not foundSet up AWS SSO (aws configure sso), IAM access keys (aws configure), environment variables, or AWS_PROFILE
PROFILE_NOT_FOUNDAWS profile "<profile>" not foundList available profiles, or configure a new one: aws configure --profile <profile>
CREDENTIALS_FILE_MISSINGAWS credentials file not foundSet up AWS SSO, IAM access keys, environment variables, or AWS_PROFILE
ACCESS_KEY_INVALIDAWS access key is invalid or has been deactivatedCheck the IAM console, run aws configure, or generate new access keys
SESSION_TOKEN_EXPIREDAWS session token has expiredSSO users: aws sso login. Assumed roles: re-run your assume-role command
SSO_SESSION_EXPIREDAWS SSO session has expired for profile "<profile>"Run aws sso login --profile <profile>
NOT_AUTHENTICATEDNot authenticated to Wraps PlatformRun wraps auth login, or provide --token / WRAPS_API_KEY
ORG_NOT_FOUNDCould not determine organizationPass --org, or sign in first: wraps auth login

IAM & Permissions

CodeMessageSolution
IAM_PERMISSION_DENIEDPermission denied: <action> on <resource>Your credentials lack the permission. View required permissions: wraps permissions --json
SES_PERMISSION_DENIEDSES permission denied: <action>wraps permissions --service email --json
DYNAMODB_PERMISSION_DENIEDDynamoDB permission deniedNeeds CreateTable, DeleteTable, DescribeTable, UpdateTable
LAMBDA_PERMISSION_DENIEDLambda permission deniedNeeds CreateFunction, UpdateFunctionCode, DeleteFunction
EVENTBRIDGE_PERMISSION_DENIEDEventBridge permission deniedNeeds PutRule, PutTargets, DeleteRule
SQS_PERMISSION_DENIEDSQS permission deniedNeeds CreateQueue, DeleteQueue, GetQueueAttributes
CLOUDWATCH_LOGS_PERMISSION_DENIEDCloudWatch Logs permission deniedNeeds logs:DescribeLogGroups, logs:FilterLogEvents, logs:StartLiveTail
ROUTE53_PERMISSION_DENIEDRoute53 permission deniedNeeds ChangeResourceRecordSets, ListHostedZones (optional — add DNS records manually instead)
IAM_ENTITY_NOT_FOUNDIAM entity not foundRun wraps platform connect

Region & AWS Limits

CodeMessageSolution
INVALID_REGIONInvalid AWS region: <region>Use a valid AWS region like us-east-1, eu-west-1, ap-southeast-1
REGION_REQUIREDRegion is required and could not be determinedPass --region or set AWS_REGION
REGION_REQUIRED_FOR_SETCould not determine which Region to changePass --region <r> with the Region you want to change
AWS_THROTTLEDAWS request was throttledWait and retry. Request a quota increase if this happens repeatedly
AWS_LIMIT_EXCEEDEDAWS service limit exceededRequest a quota increase in Service Quotas

Stack & Deployment

CodeMessageSolution
NO_STACKNo Wraps infrastructure found in this AWS accountRun wraps email init
STACK_EXISTSStack "<stackName>" already existsTo update: wraps email upgrade. To remove: wraps destroy --stack <stackName>
STACK_LOCKEDThe Pulumi stack is locked from a previous runRemove ~/.wraps/pulumi/.pulumi/locks (local), or delete the lock object under .pulumi/locks/ in your wraps-state-* bucket (S3)
PULUMI_ERRORInfrastructure deployment failed: <message>Check your AWS permissions and try again
PULUMI_NOT_INSTALLEDPulumi CLI is not installedInstall via brew/curl/choco, or download from pulumi.com/docs/install
RESOURCE_CONFLICTResource already exists: <resourceName>Diagnose and clean up: wraps email doctor --cleanup
S3_STATE_BUCKET_CREATION_FAILEDFailed to create S3 state bucket: <bucketName>Ensure s3:CreateBucket, s3:PutBucketEncryption, s3:PutBucketVersioning, or export WRAPS_LOCAL_ONLY=1
S3_STATE_ACCESS_DENIEDAccess denied to S3 state bucketEnsure s3:GetObject, s3:PutObject, s3:ListBucket on wraps-state-*, or export WRAPS_LOCAL_ONLY=1
STATE_MIGRATION_FAILEDFailed to migrate Pulumi state to S3Local state is still intact. export WRAPS_LOCAL_ONLY=1 to skip migration
SELFHOST_NO_LOG_GROUPSNo self-hosted log groups found in <region>Check wraps selfhost status, or target a different region
SELFHOST_NO_LOG_GROUPS_FOR_SOURCENo <source> log groups in this deploymentDrop the filter: wraps selfhost logs
LAMBDA_FUNCTION_NOT_FOUNDAgent enforcer Lambda not foundDeploy it: wraps email agent create
DYNAMODB_TABLE_NOT_FOUNDAgent policy table not foundDeploy it: wraps email agent create

Email / SES

CodeMessageSolution
SES_MESSAGE_REJECTEDSES rejected the message: <detail>Sandbox with unverified recipient, unverified sender identity, or receiving-only domain. Check wraps email status / wraps email doctor
SES_MAIL_FROM_NOT_VERIFIEDSES MAIL FROM domain is not verified: <detail>Check DNS records: wraps email verify
SES_ACCOUNT_SENDING_PAUSEDSES account-level sending is pausedCheck the SES console Reputation Dashboard
SES_CONFIG_SET_SENDING_PAUSEDSES configuration set sending is pausedResume it in the SES console, or send without that configuration set
SES_CONFIG_SET_MISSINGSES configuration set does not exist: <detail>Create it in the SES console, switch regions, or remove ConfigurationSetName
EVENT_DESTINATION_NOT_FOUNDEvent destination not found for <domain>Run wraps email upgrade
INVALID_EVENT_DESTINATIONEvent destination for <domain> is not an EventBridge destinationRun wraps email upgrade
EVENT_TYPES_MISSING_SUPPRESSION_EVENTSeventTracking.events is missing required event type(s): <missing>BOUNCE and COMPLAINT must always be included in eventTracking.events
INVALID_SES_PRICING_PLANNo pricing plan specifiedPass --set with one of the valid pricing plans
SES_PRICING_PLAN_CHANGE_REJECTEDSES rejected the pricing plan change: <detail>Check the current plan: wraps email plan

Inbound Email

CodeMessageSolution
INBOUND_REGION_NOT_SUPPORTEDSES email receiving is not supported in <region>Deploy in us-east-1, us-west-2, or eu-west-1
INBOUND_REQUIRES_OUTBOUNDInbound email requires outbound email infrastructureRun wraps email init, then wraps email inbound init
RECEIPT_RULE_SET_CONFLICTAnother receipt rule set is active: <activeRuleSet>Wraps will activate wraps-inbound-rules, deactivating the current set
INBOUND_TEST_SEND_FAILEDFailed to send inbound test email to <recipient>Check wraps email status / wraps email doctor
INBOUND_TEST_MAIL_FROM_NOT_VERIFIEDCustom MAIL FROM domain is not verified for <domain>Verify DNS records: wraps email verify
INBOUND_TEST_MESSAGE_REJECTEDSES rejected the inbound test send: <message>Sandbox with unverified recipient, unverified sender domain, or receiving-only domain. Check wraps email status / doctor
INBOUND_TEST_SENDING_PAUSEDSES sending is paused for this accountCheck the SES console Reputation Dashboard
INBOUND_TEST_PERMISSION_DENIEDIAM permission denied: ses:SendEmail in <region>wraps permissions --service email --json

Reply Threading

CodeMessageSolution
REPLY_SECRET_PARAMETER_MISSINGSSM parameter for <domain> was not createdRun wraps email reply status to diagnose, or retry the init
REPLY_REQUIRES_INBOUNDReply threading requires inbound email infrastructureDeploy inbound first: wraps email inbound init
REPLY_NO_INBOUND_DOMAINSNo inbound domains configuredAdd one: wraps email inbound add --domain yourapp.com
REPLY_INBOUND_DOMAIN_NOT_FOUNDDomain <target> is not configured for inbound emailAdd it to inbound first: wraps email inbound add <target>
REPLY_ALREADY_ENABLEDReply threading is already enabled for <target>To rotate the signing secret: wraps email reply rotate --domain <target>
REPLY_MISSING_DOMAINSpecify a domain or use --allwraps email reply init --domain yourapp.com, or --all
REPLY_ROTATE_MISSING_DOMAIN--domain is required for rotatewraps email reply rotate --domain yourapp.com
REPLY_NOT_ENABLEDReply threading is not enabledEnable it first: wraps email reply init --domain yourapp.com
REPLY_DOMAIN_NOT_ENABLEDReply threading is not enabled for <domain>Enable it first: wraps email reply init --domain <domain>
REPLY_DESTROY_MISSING_DOMAINSpecify a domain or use --allwraps email reply destroy --domain yourapp.com, or --all
REPLY_DECODE_MISSING_ADDRESSUsage: wraps email reply decode <token>@r.mail.yourapp.comProvide a signed reply address
REPLY_DECODE_MALFORMED_ADDRESSAddress must be in the form <token>@r.mail.example.comPass a full signed reply address

SMS

CodeMessageSolution
SMS_NOT_CONFIGUREDSMS infrastructure not foundRun wraps sms init
SMS_PHONE_NOT_VERIFIEDPhone number registration not completeToll-free numbers require registration (15+ days). Check status in the AWS console
SMS_OPTED_OUTDestination number <phoneNumber> has opted outThe recipient can opt back in by texting START
SMS_SPENDING_LIMITAWS SMS spending limit reachedRequest a spending limit increase in the AWS console
SMS_INVALID_PHONE_NUMBERInvalid phone number format: <phoneNumber>Use E.164 format, e.g. +14155551234
SMS_INVALID_COUNTRIESInvalid --countries value: <raw>Comma-separated ISO 3166-1 alpha-2 codes, e.g. --countries US,CA,GB
SMS_INVALID_VOLUMEInvalid --volume value: <raw>Positive whole number of messages per month
SMS_SIMULATOR_LIMITSimulator daily message limit reached (100 messages)Upgrade: wraps sms upgrade --phone-type toll-free

SMTP

CodeMessageSolution
SMTP_CREDENTIALS_NOT_FOUNDSMTP credentials not foundwraps email upgrade and select "Enable SMTP credentials"
SMTP_REQUIRES_SENDINGSMTP credentials require email sending to be enabledwraps email upgrade and select "Custom configuration"

Templates & Config

CodeMessageSolution
WRAPS_CONFIG_NOT_FOUNDwraps/wraps.config.ts not foundInitialize templates first: wraps email templates init
TEMPLATE_COMPILATION_FAILEDFailed to compile template "<name>": <error>Check your template for syntax errors and valid imports
TEMPLATE_PUSH_FAILEDFailed to push template "<name>": <error>Check your API key and network connection
TEMPLATES_DIR_EXISTSwraps/ directory already existsUse --force to overwrite: wraps email templates init --force

CLI Usage & Automation

CodeMessageSolution
NON_INTERACTIVE_INPUT<what> is required in non-interactive modePass the required flag, or run in an interactive terminal
UNKNOWN_COMMANDUnknown <command kind>: <what was typed>Run wraps --help, or use one of the commands listed in the error's suggestion
MISSING_REQUIRED_FLAGA required flag is missing in JSON modeProvide the flag named in the error message
JSON_REQUIRES_FORCE--force flag is required in JSON mode for destructive operationsAdd --force to the command
CONFIRMATION_REQUIREDConfirmation required to change your SES pricing planPass --yes to skip the confirmation prompt
OPERATION_CANCELLEDOperation cancelledPass --region to skip the interactive prompt
INVALID_LOG_SOURCEUnknown --source value: <value>Valid sources: api, web, workers, other, all
INVALID_LOG_WINDOWInvalid --since value: <value>Use a positive number followed by s, m, h, or d
UNKNOWN_ERRORAn unexpected error occurredThe thrown value was not a recognized WrapsError. Check the CLI logs for details

Exit Codes

Every command exits 0 on success and 1 on error, with one exception.

CommandExit codeMeaning
Any command0Success
Any command1Error
wraps email check0Deliverability grade A or B
wraps email check1Deliverability grade C or D
wraps email check2Deliverability grade F
wraps email check4Check itself failed to run, or grade was unrecognized

In --json mode, errors are still written to stdout as a JSON envelope — the exit code is what signals failure to scripts:

JSONerror-envelope.json
{  "success": false,  "command": "email.init",  "error": {    "code": "<one of the CLI error codes below>",    "message": "...",    "suggestion": "...",    "docsUrl": "https://wraps.dev/docs/..."  }}

SDK Error Classes

Email SDK (@wraps.dev/email)

WrapsEmailError

Base class every other email SDK error extends. Use it for a single catch-all instanceof check that covers all of them.

SESError

Thrown when an AWS SES API call fails.

PropertyTypeDescription
codestringMessageRejected, Throttling, AccountSuspended, MailFromDomainNotVerified
requestIdstringAWS request identifier
retryablebooleanWhether the request can be retried
DynamoDBError

Thrown when an email history read/write operation fails.

PropertyTypeDescription
codestringDynamoDB error code
requestIdstringAWS request identifier
retryablebooleanWhether the request can be retried
ValidationError

Thrown when input parameters are invalid.

PropertyTypeDescription
fieldstringWhich field failed validation
messagestringHuman-readable error description
CredentialsError

The AWS credential chain produced nothing usable, so no request was ever signed. The message lists every way to supply credentials — SSO, access keys, environment variables, a named profile, or the constructor — without ranking one over another.

PropertyTypeDescription
causeunknownThe underlying AWS SDK error, for debugging
SandboxError

Extends SESError. SES rejected the send because an identity involved is not verified in the region the request went to. Two unrelated causes produce this one AWS error — a region mismatch and the SES sandbox — so the message names the region actually used and walks through both, including the mailbox-simulator address that proves sending works without production access.

PropertyTypeDescription
regionstring | undefinedThe region this client sent to, when resolvable

SMS SDK (@wraps.dev/sms)

WrapsSMSError

Base class every other SMS SDK error extends. Use it for a single catch-all instanceof check that covers all of them.

SMSError

Thrown when an AWS End User Messaging API call fails.

PropertyTypeDescription
codestringAWS error code
retryablebooleanWhether the request can be retried
ValidationError

Thrown when input parameters are invalid.

PropertyTypeDescription
fieldstringWhich field failed validation
messagestringHuman-readable error description
OptedOutError

Thrown when the recipient has opted out of receiving messages.

PropertyTypeDescription
phoneNumberstringThe phone number that opted out
RateLimitError

Thrown when the sending rate limit has been exceeded.

PropertyTypeDescription
retryAfternumberSeconds to wait before retrying

No Automatic Retries

The SDKs do NOT automatically retry failed requests. If retryable is true, implement your own retry logic using the pattern below.

Retry Pattern

Use exponential backoff when retrying failed requests. This example uses a simple retry loop with increasing delays.

TypeScriptretry-pattern.ts
import { WrapsEmail, SESError } from '@wraps.dev/email';const email = new WrapsEmail();async function sendWithRetry(params, maxRetries = 3) {  for (let attempt = 0; attempt < maxRetries; attempt++) {    try {      return await email.send(params);    } catch (error) {      if (error instanceof SESError && error.retryable && attempt < maxRetries - 1) {        await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));        continue;      }      throw error;    }  }}

Error Handling Example

Catch and handle specific error types to provide appropriate responses in your application.

TypeScripterror-handling.ts
import { WrapsEmail, SESError, DynamoDBError, ValidationError } from '@wraps.dev/email';const email = new WrapsEmail();try {  await email.send({    from: 'hello@yourdomain.com',    to: 'user@example.com',    subject: 'Hello',    html: '<p>Hello!</p>',  });} catch (error) {  if (error instanceof ValidationError) {    console.error('Invalid input:', error.field, error.message);  } else if (error instanceof SESError) {    console.error('SES error:', error.code, error.retryable);  } else if (error instanceof DynamoDBError) {    console.error('DynamoDB error:', error.code, error.retryable);  }}

Next Steps

Email SDK

Full API reference for the @wraps.dev/email TypeScript SDK.

View Reference
SMS SDK

Full API reference for the @wraps.dev/sms TypeScript SDK.

View Reference
AWS Setup

Configure AWS credentials and permissions for Wraps.

View Guide