Troubleshoot failed sends
Diagnose failures by the exported error class, stable code, adapter, and delivery classification.
Start with the error code. Provider messages alone do not tell you whether the failure happened before or after possible dispatch.
Validation fails before network work
EmailValidationError means the common message, route, capability, schedule, or adapter-specific check failed.
Check:
from, at least oneto,subject, andtextorhtmlare present.- Every attachment has exactly one of
contentorpath. sendAthasZor a numeric offset.- Every fallback adapter supports all non-empty fields.
- Adapter-specific recipient and tag limits match the message.
Run the same path without sending:
EMAIL_SDK_TELEMETRY=0 npx email-sdk send \
--adapter resend \
--from hello@example.com \
--to user@example.com \
--subject "Validation smoke test" \
--text "Dry run only." \
--dry-runAdapter name is missing
EmailAdapterNotFoundError includes the unregistered adapter. Construction catches unknown defaults and client fallbacks; runtime strings can still reach this error.
npx email-sdk adaptersOne adapter failed
EmailAdapterError includes adapter, optional HTTP status and requestId, retryable, and delivery.
not_sentmay advance to fallback.unknownstops fallback unless you explicitly configured continuation.
Every route failed
EmailRouteError.failures contains ordered EmailAdapterError values. Inspect each adapter and delivery value, then keep the full chain in server-side diagnostics without exposing provider bodies to users.
Personalized recipients all failed
EmailAllRecipientsFailedError.failures means sendPersonalized accepted no recipients. Partial success resolves instead, with both accepted and rejected arrays.
Middleware or abort stopped the route
EmailMiddlewareError.phase identifies before_send, after_send, or on_error. EmailAbortError means the signal stopped active work or backoff and prevented later retry/fallback.
Configuration is present but delivery still fails
doctor checks required values, not provider account state. A live test can still fail because of sender verification, sandbox restrictions, API scope, region, account review, or rate limits.
Error reference
Open the exact class and field contract for each code.
Adapter docs
Check provider-specific options and account requirements.
