Trawley

MCP Error Codes

Every error the Trawley MCP server returns lands in a shared envelope with a machine-stable code, a next_action contract, and a human-readable message. This page is the canonical reference.

The error envelope

Every tool returns the same shape. Read next_action first — it tells your agent what to do without parsing English.

{
  "isError": true,
  "content": [{ "type": "text", "text": "{...same JSON as below}" }],
  "structuredContent": {
    "code": "SCRAPER_TEAM_MISMATCH",
    "message": "This API key cannot access scrapers in team 'beta'.",
    "recoverable": false,
    "next_action": "prompt_user",
    "request_id": "req_01H...",
    "docs_url": "https://trawley.ai/docs/mcp/errors#scraper_team_mismatch"
  }
}

next_action values

  • fix_input The caller passed bad args. Edit and retry. Re-running with the same input keeps failing.
  • retry_after_delay Transient. Wait retry_after_ms and retry. ALWAYS pairs with that field.
  • prompt_user Surface the message to the human. The agent cannot resolve it alone (e.g. plan limit, wrong team).
  • give_up Terminal. Do not retry. The recoverable bit will always be false.

Code reference

Sorted alphabetically. Anchor links match the docs_url returned in the error envelope.

AGENT_LOOP_CONCURRENCY

retry_after_delayrecoverable

Your team has hit its concurrent scraper-build cap. Another build is still in progress.

What to do

Wait the suggested retry_after_ms (typically 5s) and call trawley_build_scraper again. If you see this repeatedly, the concurrent build limit is plan-scoped — upgrade or cancel an in-flight build.

AGENT_LOOP_FAILED

retry_after_delayrecoverable

The build agent failed before or during the conversation (model 5xx, transient infra).

What to do

Wait retry_after_ms (typically 5s) and retry. If the same request_id keeps failing, log the request_id and reach out — server-side traces are correlated by it.

ALREADY_COMMITTED

give_upterminal

The agent already committed a scraper on this turn.

What to do

Stop the current turn. A single trawley_build_scraper call may commit at most once. Start a fresh build (new request) if more changes are needed — the previously committed scraperId is returned in the structuredContent.

API_KEY_REVOKED

give_upterminal

The API key was disabled by a team admin between auth and the write attempt.

What to do

Do not retry. Prompt the user to rotate or re-enable the API key in the Trawley dashboard (Team Settings → API Keys).

COMMIT_FAILED

retry_after_delayrecoverable

The transactional write for a scraper commit hit an unexpected database error.

What to do

Retry after the suggested delay (typically 2s). If the same retry_after_ms loop persists, log the request_id and reach out — repeated COMMIT_FAILED is a server-side incident.

COMMIT_INSUFFICIENT_CONFIG

fix_inputrecoverable

The scraper config is missing required pieces (entities, fields, or a list-page selector).

What to do

Read the message field — it names the failing requirement (e.g. `scrapeEntities[0].fields must be non-empty`). Re-run trawley_build_scraper with a goal that prompts the agent to add the missing pieces.

INTERNAL_ERROR

retry_after_delayrecoverable

A catch-all for unexpected database, network, or runtime failures.

What to do

Retry after the suggested delay (typically 5s). If the same code surfaces repeatedly with the same arguments, log the request_id and contact support.

JOB_NOT_FOUND

fix_inputrecoverable

The supplied jobId does not match any job on the supplied scraperId.

What to do

Re-fetch valid job ids via trawley_get_scraper (returns the 5 most recent) and re-call with one of those. Common cause: the jobId came from a different scraper or has been deleted by retention.

NO_JOBS_YET

prompt_userterminal

trawley_check_job was called with no jobId, but the scraper has never run.

What to do

Tell the user the scraper exists but has no jobs yet. Either trigger a run via the dashboard, schedule the scraper, or POST a job via the workers API. Re-calling trawley_check_job with the same args will keep returning this code.

PLAN_LIMIT_EXCEEDED

prompt_userterminal

The team's monthly API call quota for this surface (search, results, etc.) is exhausted.

What to do

Tell the user their plan limit is reached. Link them to the pricing page (the message field carries a docs_url). The same call will fail until the quota resets or the team upgrades.

RATE_LIMIT_PER_SECOND

retry_after_delayrecoverable

Too many MCP requests in a single second from this API key (token-bucket throttle).

What to do

Wait retry_after_ms (≤1s) and retry. The Retry-After HTTP header carries the same value. If you hit this repeatedly, batch tool calls or stagger them — the bucket is per API key.

RESULT_NOT_FOUND

fix_inputrecoverable

The supplied resultId does not exist on the supplied scraper, or has been deleted.

What to do

Re-call trawley_search or trawley_hybrid_search to get fresh row ids and re-fetch. Result ids are NOT stable across re-scrapes — a job that re-runs after retention prunes may yield new ids for the same logical row.

SCRAPER_NOT_FOUND

fix_inputrecoverable

The supplied scraperId does not exist within this team's scope.

What to do

Re-call trawley_list_scrapers to refresh the inventory. The id may have a typo, may have been deleted, or may never have existed under this API key.

SCRAPER_STALE

fix_inputrecoverable

Optimistic-concurrency check failed: the scraper was updated by another caller since you last read it.

What to do

Re-read the scraper via trawley_get_scraper to pick up the latest updatedAt and reapply your changes on the fresh snapshot. Do NOT blindly retry the same expectedUpdatedAt — it will keep failing.

SCRAPER_TEAM_MISMATCH

prompt_userterminal

The supplied scraperId belongs to a different team than the API key.

What to do

Tell the user the id is for another team. Do not retry with the same id. The user must either switch teams (and use a different API key) or call trawley_list_scrapers to find the right id.

SEARCH_FAILED

retry_after_delayrecoverable

The underlying v1 search call returned an unexpected error (not a 429, not a team mismatch).

What to do

Retry after the suggested delay (typically 2s). If the failure persists, the scraper may not yet have results indexed — call trawley_get_scraper to check job health.

URL_NOT_ALLOWED

fix_inputrecoverable

The build agent tried to navigate to a denylisted URL (RFC1918, loopback, link-local, or cloud-metadata endpoint).

What to do

Re-call trawley_build_scraper with a public URL. Trawley refuses to scrape internal or metadata endpoints to prevent SSRF; this is by design and cannot be overridden via configuration.

Need more context?

See the getting-started guide for install steps in Claude Code, Cursor, and Codex, or the tool reference for per-tool argument shapes and response examples.