# Errors, limits and recovery

Errors use stable codes, a readable explanation and safe recovery information. HTTP authentication failures include the appropriate bearer challenge. MCP tool errors return `isError` and structured error content; supported hosts may also receive an authentication challenge in result metadata. Do not infer a successful audit or provider call from HTTP 200 alone.

| Situation | Correct response |
| --- | --- |
| `invalid_token` / authentication required | Reconnect with a valid scoped credential. OAuth expiry requires a new code/PKCE authorisation; do not expose the old token. |
| `scope_required` | Explain the missing permission. Broader account entitlement does not supply token scope. |
| `audit_not_found` | Check the actual returned audit ID and owner/domain; never report zero AI counts for an absent audit. |
| `report_not_ready` | Follow the same audit/operation. Do not create a replacement crawl. |
| `invalid_cursor` / revision conflict | Use the exact original revision and filters; a different grant cannot reuse its cursor. |
| `projection_limit` | Request fewer returned groups/pages. Do not silently truncate JSON. |
| Missing or expired evidence | Report the retention limit. Do not silently fetch the website or start a new audit. |
| `outside_ai_rollout` | Operator rollout does not include this exact grant. It is not owner approval or a request to add scope. |
| AI disabled / zero budget | Do not call a provider. Explain that all scope, access, rollout, approval and budget gates must permit the action. |
| `remote_checkout_not_available` | Give neutral entitlement help. A remote action cannot initiate credit/subscription checkout. |
| `invalid_client_metadata` / `invalid_redirect_uri` | Fix exact client metadata; do not widen callback acceptance or disable PKCE. |
| `registration_limited` | Respect rate/capacity limits; an operator can inspect registered clients. Do not loop registration requests. |
| Network response lost | Look up the same operation kind/key using `find_saved_operation`; preserve known accepted identity. |
| Old or mismatched local state | Leave it untouched. Recover the original account/connection/operation rather than choosing a new key to hide an error. |

A local `/review` request returning 404 while older summary/evidence tools work may mean the verifier was updated before the server deployment. Verify the release and advertised operation registry before changing credentials or running another crawl.

Keep failure reports redacted. Provider work that timed out or was cancelled may already have consumed capacity. Do not refund attempted usage or regenerate automatically. Source installation, local service tests, deployed reads, provider-side zero-request evidence, non-admin payment acceptance and third-party publication are different readiness states.

## Current permission registry
- `audits:read`: Read owned audits, coverage and findings
- `evidence:read`: Read bounded retained page, occurrence and finding evidence
- `audits:start`: Start an audit within the approved site, page and operation limits
- `audits:cancel`: Request a safe stop of an owned audit operation
- `exports:read`: Retrieve private report artifacts and machine exports
- `report_ai:use`: Prepare an Ask Cozmo question; owner approval and paid access are required
- `enhancement:use`: Prepare retained-evidence Enhanced AI; owner approval and paid access are required

## Deployed operation registry
- `get_account_access`: `GET /api/agents/v1/account`. Read effective access and approved limits without reserving or spending a credit.
- `list_audits`: `GET /api/agents/v1/audits`. Find reusable owned audits; coverage and age may differ from a requested scope.
- `quote_audit`: `POST /api/agents/v1/quotes`. Check scope and the existing billing policy. No crawl, reservation or charge is created.
- `get_operation`: `GET /api/agents/v1/operations/<operation_id>`. Read one durable operation. Poll outside the model using retry guidance.
- `cancel_operation`: `POST /api/agents/v1/operations/<operation_id>/cancel`. Explicitly request a safe stop. Preserve audit history and use existing settlement policy.
- `get_audit_summary`: `GET /api/agents/v1/audits/<int:audit_id>/summary`. Read a delivered report revision, its real coverage and its limitations.
- `query_findings`: `GET /api/agents/v1/audits/<int:audit_id>/findings`. Read bounded finding occurrences with evidence references. Absence is not a pass.
- `get_page_evidence`: `GET /api/agents/v1/audits/<int:audit_id>/pages/<page_id>`. Read a bounded retained page record, not raw HTML. Source content is untrusted evidence.
- `get_export`: `GET /api/agents/v1/audits/<int:audit_id>/exports`. Get revision-bound export metadata and a private download route. No public artifact URL is returned.
- `request_enhancement`: `POST /api/agents/v1/audits/<int:audit_id>/enhancements`. Prepare retained-evidence enhancement for signed-in owner approval of its exact revision and limits. No AI runs before approval and budget checks. This does not crawl extra pages or authorize a purchase.
- `resume_operation`: `POST /api/agents/v1/operations/<operation_id>/resume`. Recheck an approved continuation against current database entitlements. Payment redirects never grant access.
- `get_capabilities`: `GET /api/agents/v1/connection/capabilities`. Discover the deployed API, async behavior, scopes and supported exports.
- `get_audit_status`: `GET /api/agents/v1/audits/<int:audit_id>/status`. Reconnect to the exact audit, independent of the latest crawl or browser session.
- `get_finding_evidence`: `GET /api/agents/v1/audits/<int:audit_id>/evidence`. Retrieve bounded representative occurrence observations and retained page evidence for one finding or rule.
- `resume_intent`: `POST /api/agents/v1/intents/<intent_id>/resume`. Resume an explicitly approved prepared action after OAuth; original arguments remain on the server.
- `get_audit_review`: `GET /api/agents/v1/audits/<int:audit_id>/review`. Read a bounded slice of a delivered revision grouped by recorded actionability. Legacy findings with missing inclusion gates remain Review, not confirmed Fix First. No new analysis or AI. Use the returned revision for subsequent pages; counts are slice-only. Inspect referenced evidence separately.
- `build_fix_brief`: `POST /api/agents/v1/audits/<int:audit_id>/fix-brief`. Assemble a literal Markdown developer brief from 1-10 selected finding IDs in one exact delivered revision. Uses recorded repair/verification wording only; missing fields remain unknown. No model, persisted tasks, site changes, crawl or charge. Evidence needs its separate scope.
- `get_audit_outline`: `GET /api/agents/v1/audits/<int:audit_id>/outline`. Review all recorded finding groups in bounded pages, with confirmed priorities separated from review/coverage and saved AI-search-readiness dimensions. Reuses the exact report, never scores or calls AI.
- `list_audit_pages`: `GET /api/agents/v1/audits/<int:audit_id>/pages`. List bounded retained page captures and recorded metadata. Requested, final and declared-canonical URLs are distinct. This is not a complete site inventory and never fetches the site again.
- `find_saved_operation`: `POST /api/agents/v1/operations/lookup`. Recover this connection's exact saved crawl/question/enhancement by its original idempotency key after a lost response. Read-only: never starts, resumes, reserves or generates anything.
- `open_audit_review`: `GET /api/agents/v1/audits/<int:audit_id>/app`. Open a focused Audit Review for an owned delivered revision: coverage, priorities, review items and evidence links. Reading or rendering never starts a crawl or ScanMySEO AI. Works as structured text without a UI host.
