Skip to content

Fix error related to case sensitivity for email routing#992

Merged
threepointone merged 1 commit intomainfrom
fix/case-insensitive-email-routing
Feb 26, 2026
Merged

Fix error related to case sensitivity for email routing#992
threepointone merged 1 commit intomainfrom
fix/case-insensitive-email-routing

Conversation

@Muhammad-Bin-Ali
Copy link
Contributor

Resolves #988

Fix email routing for mail-server-lowercased agent names

Closes the case-sensitivity gap in routeAgentEmail where email infrastructure lowercases addresses before delivery, causing PascalCase agent bindings to fail lookup.

Problem

Email servers normalize addresses to lowercase. When a user sends to SomeAgent+123@domain.com, the Worker receives someagent+123@domain.com. The router's lookup map only contained:

  • SomeAgent (original binding name)
  • some-agent (kebab-case, added in v0.0.106)
    The plain-lowercase someagent had no match, producing:

Agent namespace 'someagent' not found in environment. Available agents: SomeAgent

Fix

Register a third key — key.toLowerCase() — in the agent map alongside the existing original and kebab-case entries. The map now contains:

  • SomeAgent → namespace
  • some-agent → namespace
  • someagent → namespace
    Also refactored the cache to store original binding names separately, so the error message lists only original names without lowercase/kebab duplicates.

Generated by Opencode

@changeset-bot
Copy link

changeset-bot bot commented Feb 25, 2026

🦋 Changeset detected

Latest commit: eabdf7a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agents Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 25, 2026

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/agents@992
npm i https://pkg.pr.new/cloudflare/agents/@cloudflare/ai-chat@992
npm i https://pkg.pr.new/cloudflare/agents/@cloudflare/codemode@992
npm i https://pkg.pr.new/cloudflare/agents/hono-agents@992

commit: eabdf7a

@threepointone
Copy link
Contributor

/bonk review this

@ask-bonk
Copy link
Contributor

ask-bonk bot commented Feb 26, 2026

Now I have a complete picture of the changes. Here's my review:


Code Review: Fix case-sensitivity for email routing

Summary

The PR adds a third lookup key (key.toLowerCase()) to the agent namespace map in routeAgentEmail, so that email addresses lowercased by mail infrastructure correctly resolve to PascalCase bindings. It also refactors the cache to store original binding names separately, improving error messages.

What's Good

  1. Correct diagnosis. The bug is real — email servers normalize the local part to lowercase, so SomeAgent+id@domain.com arrives as someagent+id@domain.com. The existing map only had SomeAgent and some-agent, missing the plain someagent form.

  2. Minimal, surgical fix. Only one line of production logic added (map[key.toLowerCase()] = value), plus a small refactor of the cache structure. Clean and low-risk.

  3. Better error messages. The old code filtered original names from the map with a heuristic (.filter((key) => !key.includes("-"))), which would incorrectly exclude bindings that legitimately contain hyphens. Storing originalNames separately is strictly more correct.

  4. Test coverage. Three new test cases cover the exact failure scenario — lowercase versions of emailagent, casesensitiveagent, and usernotificationagent are all verified.

  5. Changeset present. Properly described patch changeset.

Issues

Minor — package-lock.json noise

The package-lock.json diff removes "peer": true from several unrelated packages (@ai-sdk/openai-compatible, @babel/core, @cloudflare/kumo, vite, etc.). These changes are unrelated to the email routing fix and appear to be an artifact of running npm install with a different dependency resolution state. While harmless, they add noise to the diff. Consider whether these should be in a separate commit or if they're expected from a lockfile refresh.

Nit — potential key collision

If a user has two different bindings where camelCaseToKebabCase(A) produces the same string as B.toLowerCase() (or similar overlaps), later entries in the Object.entries iteration will silently overwrite earlier ones. This is a pre-existing issue (it already existed for the kebab-case key) and is highly unlikely in practice, but worth noting. Not a blocker.

Nit — the resolver doesn't lowercase its input

The createAddressBasedEmailResolver extracts the agent name directly from the email address, so if the email arrives as someagent+id@domain.com, the resolver returns agentName: "someagent". The fix works because the map now contains a someagent key. But an alternative approach would be to lowercase the lookup key at query time (cached.map[routingInfo.agentName.toLowerCase()]), which would handle all case variations with a single normalization point rather than registering multiple keys. The current approach is fine — just a design observation, not a requested change.

Verdict

The fix is correct, well-tested, and low-risk. The package-lock.json changes are noisy but harmless. Approve — ready to merge.

github run

Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@threepointone threepointone merged commit 4fcf179 into main Feb 26, 2026
4 checks passed
@threepointone threepointone deleted the fix/case-insensitive-email-routing branch February 26, 2026 04:27
@github-actions github-actions bot mentioned this pull request Feb 26, 2026
dmmulroy pushed a commit that referenced this pull request Feb 26, 2026
Co-authored-by: Muhammad Ali <muhammadali@cloudflare.com>
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.

createAddressBasedEmailResolver is case-sensitive

2 participants