Skip to content

Error Handling

All tool errors return the standard MCP error format:

{
"content": [{ "type": "text", "text": "Error message here" }],
"isError": true
}

The text field contains a plain, human-readable message (not a JSON-encoded string). Errors are actionable — they tell you what went wrong and suggest which tool to call next.

{
"text": "SCOPE_REQUIRED: \"campaigns:write\" scope is required to call campaignstack_edit_campaign. This API key cannot access it. Use campaignstack_whoami to check your current scopes."
}

Fix: Create a new API key with the required scope, or add the scope to your existing key. The scope matrix lists the scope every tool needs.

{
"text": "Workflow not found in this workspace."
}

Fix: Read the collection to get valid IDs (campaignstack_get_campaigns, campaignstack_get_workflows, campaignstack_get_lead_lists, …). With a user key (csu_), also check that workspaceId is the workspace the record lives in.

The edit_* tools take an operations array and apply each operation independently. A batch where some operations fail is not an error: the response carries one result per operation, and the failed ones say why. Read every result before reporting the batch as done.

{
"text": "Invalid input: workspaceId is required"
}

Fix: Check the tool’s input schema on its reference page and provide all required fields. Unknown fields are rejected.

{
"text": "Rate limit exceeded for campaignstack_craft_message: llm tool limit of 10 requests/minute. Retry after 12s. These limits protect the API from abuse and runaway loops — slow down or batch your calls."
}

Each API key has per-minute limits, bucketed by tool category. Defaults (override with MCP_RATE_LIMIT_*_PER_MIN):

CategoryLimit/minExamples
read120get_* tools
write30tools that change data, send or delete
llm10AI craft tools (campaignstack_craft_message)
overall240per-key ceiling across all categories

Internal server-to-server callers are exempt. Current active limits are returned on GET /health.

Fix: Slow down or batch your calls; wait the number of seconds in the message before retrying.

With a workspace key (cs_):

{
"text": "workspaceId mismatch: this API key is bound to a different workspace. Omit workspaceId (it defaults to your key's workspace) or use campaignstack_whoami to inspect your key."
}

With a user key (csu_):

{
"text": "workspaceId mismatch: you are not a member of this workspace. Use campaignstack_whoami to list your workspaces."
}

Fix: Workspace keys (cs_) are bound to one workspace — omit the workspaceId argument (it defaults to the key’s workspace), or use a key bound to the workspace you’re targeting. With a user key (csu_), pass a workspaceId of a workspace you’re a member of — call campaignstack_whoami to list them.

StatusMessageFix
401“Authentication required. Provide a valid API key as Authorization: Bearer <key> or X-Api-Key: <key> (csu_… user key or cs_… workspace key)”Add an Authorization: Bearer <api-key> header, or X-Api-Key: <api-key> if your client reserves Authorization
401“Invalid or revoked API key. Create a new key in Settings > API Keys.”Key was revoked or doesn’t exist — create a new one

CampaignStack errors consistently point to related tools. This helps AI agents self-correct:

  • “Use campaignstack_whoami to check your current scopes” — after a missing-scope error
  • “campaignstack_estimate_cost gives the number before you commit” — on every tool that spends credits
  • Tool descriptions name the neighbouring tool: campaignstack_edit_workflow says “Graph changes belong in campaignstack_edit_workflow_graph.”

This pattern enables agents to recover from errors without human intervention.

All tools enforce strict input validation via Zod schemas:

  • Required fields — missing required fields return clear error messages
  • Type checking — wrong types (string where number expected) are rejected
  • Range validation — numeric limits (e.g., limit must be 1-100) are enforced
  • Unknown fields — extra fields not in the schema are rejected