Errors
Seamward returns stable, machine-matchable error identifiers. This page lists what each one means and what to do about it, grouped by where you meet it.
Unexpected request failures
503 {"error":"mode_cutover_write_paused"} with Retry-After: 1 means
authenticated writes are temporarily paused for maintenance. Wait at least
that many seconds and retry the same request and idempotency key with bounded
backoff. Keep observation event IDs unchanged and generate a fresh ingest
signature. After an unknown outcome, recover the original operation status
before reviewing another change. See temporary write maintenance.
Connection checks
GET /v1/collector/connection returns 401 unauthenticated when credentials or
request signing fail, and 429 connection_rate_limited when its per-client limit
is reached. Check the credential pair, revocation and system clock for 401; wait
for Retry-After seconds for 429. See the connection API.
The local CLI also returns safe connection_* references for missing or conflicting
configuration, unsafe endpoints, unavailable services, invalid responses and scope
mismatches. Follow the connection-check recovery table.
Network or response failures do not mean that credentials are invalid, and a
successful connection check does not verify application startup or traffic.
The local setup MCP can return setup_metadata_unsafe when its metadata path or
ignore rules need review. It does not overwrite existing rules. Ensure
.seamward/.gitignore includes private/, runtime-validation.json,
**/setup-state.json and **/*.lock without negation rules, and check that the
metadata paths are regular, owner-controlled files, then review setup again.
Already tracked state still needs to be excluded from commits separately.
Unexpected internal failures return 500 {"error":"service_unavailable"} without
exposing database arguments or credentials. Retry with bounded backoff and contact
the operator if the failure persists. Rejected malformed transport requests return
invalid_request with their 4xx status; oversized bodies return
413 {"error":"request_too_large"}. Documented domain errors keep their specific
identifiers.
Ingestion and signing
From POST /ingest, the endpoint your backend talks to:
| Status | Body | Fix |
|---|---|---|
400 | {"error":"expected { envelopes: [...] }"} | Send a JSON object with an envelopes array |
401 | {"error":"unauthenticated"} | A header is missing or malformed, a key fails its format, or the token was revoked; recheck all three headers and rotate if unsure |
401 | {"error":"unauthenticated","reason":"malformed"} | The signature header must match t=<seconds>,v1=<64 lowercase hex> |
401 | {"error":"unauthenticated","reason":"stale"} | The signature timestamp is outside the 300-second window; sign immediately before sending and check clock sync |
401 | {"error":"unauthenticated","reason":"mismatch"} | The digest is wrong: wrong secret, or the signed string differs from the sent body byte-for-byte |
409 | {"error":"integration_not_available"} | Whole-batch race on integration ownership; retry with backoff |
429 | {"error":"workload_rate_limited"} | Pause for the Retry-After seconds header, then retry the same event IDs. No observations from this request were persisted. |
A 207 response is not an error: the batch was mixed, and each rejected item carries its own issues array. The API reference lists the per-item rejection strings.
Workload limits
Ingestion allows 600 requests and 6,000 attempted observations per integration per minute, with a shared ceiling of 30,000 observations per workspace per minute. Empty batches still consume a request. Rotating a credential does not reset its integration budget. All API instances share these fixed minute windows. Monthly usage displayed in the console remains informational.
Repair requests allow five submissions per user per workspace per minute and
20 per workspace per minute. A workspace can have at most ten proposals queued,
generating or validating, and only one active proposal per incident. A full
workspace returns 429 repair_capacity_exceeded with Retry-After: 60; wait for
pending work to finish. A duplicate incident request returns
409 repair_proposal_in_progress with the existing proposalId. Rejected
admissions create no proposal, replay dataset or queued job.
Collectors keep transient failures in their bounded local queues. Sustained traffic above these limits can exhaust that queue and increment dropped counts; monitor collector diagnostics and reduce observed traffic or batch submission frequency before retrying.
Contract API
From the workspace-scoped Contract API:
| Status | Identifier | Fix |
|---|---|---|
400 | invalid_contract | Validate the document, operation selector, and supported schema subset |
400 | invalid_contract_activation | Send the required active-version precondition and promote or rollback reason |
401 | unauthenticated | Create a new sw_api_ key or replace an expired or revoked key |
403 | insufficient_scope | Create a replacement key carrying the required integrations:read, observations:read, contracts:read, contracts:write, or contracts:activate scope; scopes cannot be edited after creation |
404 | integration_not_found, contract_not_found | Confirm the ids belong to the API key's workspace and integration |
409 | contract_version_already_exists | The declared version exists with different content or selectors; register a new immutable version |
409 | active_contract_changed | Read the active version, review it, then retry with the new precondition |
409 | contract_not_activatable | Review the version lifecycle before retrying |
503 | service_unavailable | Activation was not attempted because reanalysis was unavailable |
Console and workflow
Console-facing routes return snake_case identifiers. The ones worth recognizing:
| Status | Identifier | Meaning |
|---|---|---|
401 | unauthenticated | No valid session; sign in again |
403 | email_verification_required | Verify your account email before any other action |
403 | forbidden | Your role lacks the required permission; see members and roles |
404 | workspace_not_found | The workspace does not exist for your account. Cross-workspace access deliberately returns 404, never 403, so foreign resources are indistinguishable from missing ones |
404 | integration_not_found, incident_not_found, repair_proposal_not_found, ... | The resource is not in this workspace |
400 | idempotency_key_required | The console mutation did not carry a valid retry key. Refresh the page and submit the action again |
409 | idempotency_conflict | The same retry key was used for a different mutation. Refresh the page before trying the intended action |
409 | repair_proposal_not_approvable | The proposal has not passed validation, or was already decided |
409 | repair_proposal_not_patchable | The proposal is not validated and awaiting review, or it is not an approved legacy proposal |
409 | repair_source_patch_required | Source code is mapped, so Seamward must resolve and display the exact repository patch before approval |
409 | repair_source_not_found | No supported implementation location matched the bounded repair. Confirm the repository mapping and service path |
409 | repair_source_ambiguous | More than one source location matched. Narrow the mapped service path so Seamward can identify one implementation |
409 | replay_dataset_required | Build the replay dataset before running validation |
409 | github_repository_unavailable | The repository grant was revoked, or the installation is suspended or uninstalled; reconnect GitHub access |
409 | github_pull_request_permission_required | The GitHub App installation needs Contents and Pull requests set to Read and write |
409 | github_branch_conflict | The review branch moved since the patch was prepared; Seamward refuses to overwrite it |
503 | repair_generator_unavailable | Repair generation is not enabled for this deployment |
503 | replay_runner_unavailable | The replay runner is not available; retry later |
503 | github_not_configured | This deployment has no GitHub App configured |
Legacy internal routes are not part of the supported public API. Public and workspace-scoped contract routes use the snake_case identifiers documented above.
Integration deletion
| Status | Identifier | Fix |
|---|---|---|
400 | invalid_integration_deletion | Use the operation ID, fingerprint, and confirmation challenge from the current preview. |
400 | confirmation_mismatch | Type the exact case-sensitive Integration name. |
403 | insufficient_scope | Run seamward login again to approve seamward:setup:integrations:delete. |
404 | not_found | The Integration or deletion operation is unavailable in the authorized workspace. |
409 | deletion_preview_expired | Start again and review a new impact preview. |
409 | deletion_preview_stale | Integration-owned data changed. Start again and review the current counts. |
409 | operation_mismatch | Use the Integration and operation ID returned by the same preview. |
409 | idempotency_conflict | Retry the original request for that key, or use a new key with a new reviewed deletion. |
Assisted setup MCP
The local @seamward/setup-mcp server returns an error object containing
code, message, retryable, and recovery. Retry the same request only when
retryable is true. State, review, configuration, and permission errors need
the listed recovery step first.
For runtime_credentials_unavailable, run review_setup selecting the existing
Integration, review credentialAction: rotate, and separately approve apply_setup
only if replacement is intended. Then rerun seamward setup credentials.
Do not recreate the Integration or paste tokens into chat.
| Code | Retryable | Recovery |
|---|---|---|
setup_metadata_unsafe | No | Review metadata paths and preserve existing ignore rules. Include private/, runtime-validation.json, **/setup-state.json and **/*.lock in .seamward/.gitignore, without negation rules, then review again. Check already tracked files separately. |
plan_not_found | No | Run review_setup |
legacy_plan_requires_replan | No | Prepare and review the replacement plan |
confirmation_required | No | Supply the exact fixed confirmation for a legacy or non-native trust boundary |
approval_cancelled | No | Approval was cancelled. Wait for a new user request; do not automatically retry. |
approval_declined | No | Wait for requested changes, then review the revised proposal. |
approval_invalid | No | The client returned malformed approval. Check client approval support before retrying. |
approval_unavailable | No | For explicitly selected native approval, restart an updated client with form support. Default conversational approval does not require elicitation. Never infer approval from a failed dialog. |
no_matching_actions | No | Prepare again and choose a proposed operation |
invalid_input | No | Correct the request to match the tool schema |
scan_limit_exceeded | No | Narrow the service root, then prepare again |
generated_file_conflict | No | Review the changed generated file before preparing again |
apply_in_progress | Yes | Wait for the active local apply, then retry |
runtime_preview_expired | No | Review the current local service and traffic scripts again |
runtime_validation_in_progress | Yes | Wait for the active runtime validation, then check setup status |
runtime_service_failed | No | Fix the reviewed local service script, then review runtime validation again |
runtime_port_unavailable | No | Choose an available loopback port, update the startup options and readiness URL together, then review and approve the new runtime plan. Do not stop an unrelated service. |
runtime_credentials_unavailable | No | A retained local ingest token is missing. Recover it securely or separately approve a replacement through the supported credential flow. Do not delete or recreate the Integration or paste tokens into chat. |
runtime_readiness_failed | No | Fix service startup or the loopback readiness URL, then review again |
runtime_traffic_failed | No | Do not resend uncertain traffic; inspect the named script and check setup status |
runtime_status_failed | Yes | Repeat the same approved run; it polls status without resending completed traffic |
runtime_cancelled | No | Review again before traffic, or check status if traffic had already started |
verification_failed | No | Fix source or project checks, then prepare and apply again |
setup_state_conflict | No | Check status, then prepare and review current state |
stale_setup_lock | No | Confirm no apply is running, remove the reported lock only |
configuration_required | No | Run seamward login, then seamward setup, then restart the coding agent |
development_environment_required | No | Run source setup in Sandbox or exact legacy Development; use seamward setup --live for remote-only Live setup. Legacy Production and Staging require their exact flags |
contract_preview_expired | No | Run review_remote_setup again |
contract_activation_conflict | No | Read contract state and review the remote setup again |
authentication_required | No | Run seamward login, then seamward setup, and approve this service in its workspace environment again |
insufficient_scope | No | Run seamward login to reauthorize this workspace environment, then restart the coding agent |
integration_scope_mismatch | No | Choose the correct boundary and prepare again |
integration_mapping_required | No | Authorize or choose the matching Seamward Integrations, then review again |
contract_invalid | No | Correct the reviewed contract shape; OpenAPI webhook operations belong under webhooks |
contract_version_conflict | No | Choose a new version or review the immutable existing one |
source_verification_required | No | Run apply_local_setup and resolve source verification |
not_found | No | Verify workspace and Integration access, then review again |
remote_conflict | No | Read remote state and run review_remote_setup again |
rate_limited | Yes | Wait for the retry interval, then repeat the request |
service_unavailable | Yes | Wait for service recovery, then repeat the request |
remote_request_failed | No | Verify the request and access configuration, then review |
remote_response_invalid | No | Report the invalid service response before trying again |
plan_conflict | No | Run prepare_setup and review the current plan |
internal_error | No | Inspect local logs and report the failure |
Interrupted worker execution
| Code | Meaning | Response |
|---|---|---|
execution_interrupted | A legacy replay could not be reconstructed after worker interruption | Request a supported repair proposal; historical evidence remains available |
execution_attempts_exhausted | Repair recovery reached its three-attempt bound | Review the incident and request a new proposal after the underlying worker problem is resolved |
execution_interrupted_by_rollback | A release rollback stopped this execution before older workers started | Request a new proposal after service recovery. The failed attempt remains in the audit history |
Retired custom replay
410 custom_replay_retired means the legacy endpoint for uploading custom
adapter source has been retired. Do not retry it. Request a supported repair
proposal from the incident's Repair tab. Existing run evidence remains
readable by authorized members.
Collector-side signals
The collector never throws into your application after construction, so its failures surface as counters from stats():
| Signal | Meaning | Response |
|---|---|---|
Constructor throws Seamward Connection key is invalid / Seamward ingest token is invalid | Key fails its format check | Fix the value; formats are in configuration |
failedBatches rising | Retryable delivery failure; batch stays queued | Check endpoint URL, network egress, throttling, and service availability |
rejected rising | Ingest permanently rejected an envelope or batch | Check credentials or 207 issues, fix the cause, then send new traffic |
dropped rising | The bounded queue overflowed; oldest observations were discarded | Restore delivery, or raise maxQueueSize |
buildErrors rising | Observations failed envelope validation and were discarded | Check routeTemplate, eventType format, and status codes you pass to record() |
| skippedInspections rising | Inspection was skipped because of size, time, content type or capacity bounds | Check body types, sizes and burst volume; see resource limits |
| pendingInspections | Current bounded inspection work, a live gauge | Check whether bursts approach maxPendingInspections |
| quotaRejected rising | Monthly quota rejection, also included in rejected | Inspect the account allowance and wait until the UTC reset. Discarded telemetry is not recovered. |
| quotaResetAtSeconds greater than zero | Delivery is paused until this Unix timestamp | New traffic resumes after reset. Your application keeps running. |
See monthly mode allowances for the full 403 response and the distinction from 429 throttling.
Retry rules, in one list
- Retry:
5xx,409 integration_not_available,429, network failures. Idempotent byeventId, so redelivery is always safe. - Fix first, then retry:
400,401, per-item schema rejections. - Never retry in a loop:
403,404. A403 observation_monthly_quota_exhaustedmeans the mode allowance is exhausted until the reported UTCresetAt; other 403s require correcting permissions or scope.
Replay evidence capacity exceeded
replay_evidence_capacity_exceeded is a 409 response to replay dataset or repair
proposal creation when the current incident requires more than 1,000 fixtures.
limit and total explain the boundary. The full evidence page remains available,
including search and pagination. No dataset or proposal is created by the rejected
request. Reconciliation updates the active set as outcomes recover; rerun the
request only after its complete evidence fits the limit.
An explicitly selected dataset whose observation IDs no longer match the complete
current evidence returns 409 replay_evidence_snapshot_changed. Create a fresh
dataset or start proposal generation without selecting the stale dataset. Automatic
preparation rebuilds an immutable dataset when the current evidence changes.
Sandbox work and burst limits
| Code | Status | Recovery |
|---|---|---|
sandbox_observation_rate_limited | 429 | Reduce submitted envelopes, including duplicates and invalid items. Honor Retry-After. |
sandbox_request_rate_limited | 429 | Reduce ingest requests across the account. Honor Retry-After. |
sandbox_repair_monthly_limit | 429 | Three repair validations are used or reserved. Inspect current proposals and account usage. Wait until resetsAt for a new operation; do not repeatedly submit it. |
sandbox_execution_busy | 429 for admission; queued workers retry | One account job is running. Honor Retry-After; queued work retains its reservation. |
A monthly repair validation error returns { "error": "sandbox_repair_monthly_limit", "limit": 3, "resetsAt": "2026-10-01T00:00:00.000Z" }. The date is the next UTC
month boundary. Reads, existing operation status and credential revocation remain
available when allowances are exhausted. Review pooled usage and keys.
