Skip to content

fix(ses-inbound): lift 150 KB inbound email size cap#25

Merged
snopoke merged 4 commits intomainfrom
sk/ses-inbound-size-fix
Apr 30, 2026
Merged

fix(ses-inbound): lift 150 KB inbound email size cap#25
snopoke merged 4 commits intomainfrom
sk/ses-inbound-size-fix

Conversation

@snopoke
Copy link
Copy Markdown
Contributor

@snopoke snopoke commented Apr 30, 2026

Summary

  • Replace the receipt rule's dual S3 + Sns(encoding=BASE64) actions with a single S3 action carrying topic=self.topic. SES caps inline-SNS email payloads at 150 KB, which was bouncing inbound emails larger than ~150 KB with "Message length exceeds limit set by recipient."
  • Anymail's Amazon SES inbound webhook now sees receipt.action.type == "S3" and fetches the raw MIME from S3 via boto3, using the Fargate task role's existing s3:GetObject permission on <bucket>/inbound/*. Effective ceiling rises to the SES inbound max (40 MB); stated support remains 10 MB per the 2026-04-28 inbound-email design.
  • Adds two CDK synth tests asserting the new shape (S3Action with TopicArn; no SNSAction element) and guarding against regression.

Spec: docs/superpowers/specs/2026-04-30-ses-inbound-size-fix-design.md
Plan: docs/superpowers/plans/2026-04-30-ses-inbound-size-fix.md

Test plan

  • uv run pytest -q — 121 passed (full repo)
  • uv run pytest ocs_deploy/tests/test_ses_inbound_stack.py -v — 13 passed (including SNS topic, lambda subscription, secret, and webhook-URL regression guards)
  • uv run ruff check ocs_deploy/ — clean
  • After deploy: confirm CFN change-set shows in-place modification of the receipt rule — no resource replacement on SNS topic, bucket, secret, or subscription
  • After deploy: re-send the original 500 KB PDF to `chat.openchatstudio.com`; expect no bounce
  • After deploy: confirm Django `anymail.signals.inbound` handler entry fires in CloudWatch (Lambda forwarder HTTP 200 alone is not proof the S3 fetch worked)
  • After deploy: send a ~9 MB attachment as upper-bound smoke test (timeouts at this size would surface on the Django side, not the Lambda forwarder, since the SNS payload is now metadata-only)

🤖 Generated with Claude Code

snopoke and others added 4 commits April 30, 2026 16:39
Captures the plan to drop the inline-SNS receipt action that caps
inbound emails at 150 KB, and rely on anymail's S3 fetch path so
attachments up to 10 MB work as the original 2026-04-28 design intended.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step-by-step TDD plan for the receipt-rule action change described in
the 2026-04-30 design doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SES caps the inline SNSAction email payload at 150 KB, which bounced
inbound emails larger than ~150 KB with "Message length exceeds limit
set by recipient." Replace the dual S3 + SNSAction(encoding=BASE64)
rule with a single S3Action that uses its optional topic= parameter
to publish a metadata-only Received notification.

Anymail's Amazon SES inbound webhook recognizes receipt.action.type
== "S3" and fetches the raw MIME from S3 via boto3 using the Fargate
task role's existing s3:GetObject permission. Effective ceiling rises
to the SES inbound max (40 MB); stated support remains 10 MB per the
2026-04-28 inbound-email design.

Spec: docs/superpowers/specs/2026-04-30-ses-inbound-size-fix-design.md
@snopoke snopoke merged commit fd65177 into main Apr 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant