Error reference

test_limit_exceeded

HTTP 403 retryable: false REST and MCP

The action is valid but it would push a test-mode allowance past its cap, so it was refused before anything was written.

Why it happens

Test mode is free and therefore bounded, and the bounds are checked against a locked usage row rather than a cached count. Three separate caps produce this code: three active test inboxes per workspace, 100 retained test messages, and 10 MB of retained test content. The message and byte checks run together on inbound simulation, and the byte total includes the text, the HTML and every attachment, so a single large message can trip the cap on its own. Test content also expires after 7 days, which is why a workspace that was at the cap yesterday may be under it today without anyone deleting anything.

Every condition below was read in the implementation at the file and line given. They are the branches that raise this code, not a summary of what the name suggests.

How to fix it

  1. Delete a test inbox you are no longer using. The cap counts active inboxes, so a deleted one frees a slot.
  2. Wait for expiry if the cap is on content rather than inboxes. Test content expires after 7 days and the counters fall as it goes.
  3. Shrink the fixture. The byte check sums text, HTML and attachments, so trimming a large HTML body is usually faster than deleting messages.
  4. Do not create a second workspace to get more test capacity. The caps are per workspace and the free live allowance is per verified owner identity, so it does not renew.

Why it works this way

The storage check runs at upload reservation rather than at upload completion. Checking after the bytes arrive would mean accepting content the workspace has no room for and then deleting it, and two parallel uploads could each pass an unreserved check and together exceed the cap.

Messages you will see

The message field is written for a human reading a log and is not a contract value. Branch on code instead. These are the exact strings this code is sent with today, listed so that a search for one of them lands here.

Where it appears

These are the documented surfaces that raise it. The REST base is https://api.emailforagents.ai/v1, and the remote MCP endpoint is https://mcp.emailforagents.ai/mcp.

The response

Read request_id off the body or the x-request-id header before doing anything else. It is the only handle on one specific attempt, and for a 503 it is the only handle at all, because the underlying detail stays server-side.

HTTP/1.1 403
content-type: application/json
x-request-id: req_...

{
  "error": {
    "code": "test_limit_exceeded",
    "message": "This workspace already has the maximum number of test inboxes.",
    "request_id": "req_...",
    "retryable": false
  }
}

Verified against packages/domain/src/services.ts:1371. The status comes from ERROR_STATUS in packages/contracts/src/errors.ts, which is the one place a code is mapped to a status.

All error codes · Documentation · Quickstart