Troubleshooting

Symptom-first recovery for connection, scope, project-reach, protocol, grant/lease, and question errors — with what is safe to retry versus when a human must act.

View as Markdown
On this page

Start from the symptom and preserve durable state. Server control blocks name the stable error code, current state, permitted next operations, retryability, and any human action. If no authoritative response arrived, treat the outcome as unknown and read status before replaying a mutation.

Tools are missing or empty after setup

Classify startup before changing credentials:

  1. Not configured: add https://mcp.semel.ai/mcp with the exact Quickstart command.
  2. Starting or provider transient: retry once with bounded backoff; do not erase credentials on timeout, 429, network failure, or 5xx.
  3. Terminal OAuth: for invalid_grant, a rejected/used refresh token, missing provider refresh token, or logged-out state, stop concurrent clients sharing it and perform one harness-native login.
  4. Server has tools, model session does not: reload the session; reauthorization will not fix stale model context.
  5. Some tools exist, one is absent: request only its missing scope/capability.
  6. Require live initialize, Semel serverInfo, non-empty tools/list, and the needed tools in the current model session.

Authentication & scope errors

  • AUTHENTICATION_REQUIRED — complete one harness-native OAuth login, or have an owner rotate the named token through a secret reference.
  • AUTHORIZATION_SCOPE_MISSING — request only the scope named by the live tool/control block, then reload the session. An unchanged retry cannot work.
  • PROJECT_ACCESS_DENIED / CONTEXT_FORBIDDEN — use a reachable project/source or ask an owner to change the allowlist. Never probe for hidden project data.
  • PROTOCOL_VERSION_UNSUPPORTED — run the inspected installer and start a new session. Never mutate under incompatible or security-revoked skill bytes.

Validation, versions, and idempotency

  • PAYLOAD_REJECTED / VALIDATION_FAILED — repair the field, size, content, evidence, or prerequisite named in the safe response; do not repeatedly send the same invalid payload.
  • CONFLICTING_IDEMPOTENCY_REPLAY — the key belongs to different arguments. Read status/receipts, then use the original exact arguments or a fresh key for a genuinely new mutation.
  • BRIEF_VERSION_CONFLICT — reread the full current brief, preserve all intended replacement sections, and ask the human to resolve the substantive conflict.
  • No response / CONTROL_PLANE_UNREACHABLE — the client observed no authoritative result. Reconnect and read status before replaying with the same idempotency key.

Error codes

The full server error taxonomy. “Safe to retry” means an unchanged retry can succeed; “needs operator action” means a human must do something (approve, re-grant, re-mint) before it will.

AUTHENTICATION_REQUIREDdo not blind-retry

The request carried no valid bearer credential.

AUTHORIZATION_SCOPE_MISSINGdo not blind-retryneeds operator action

The authenticated principal is missing a required scope.

PROJECT_ACCESS_DENIEDdo not blind-retryneeds operator action

The authenticated principal has no grant to reach this project.

PROTOCOL_VERSION_UNSUPPORTEDdo not blind-retry

No compatible protocol major overlaps the caller-supported range.

GRANT_REQUIREDdo not blind-retryneeds operator action

No operator-issued execution grant exists for this session yet.

GRANT_EXPIREDdo not blind-retryneeds operator action

The execution grant is revoked, expired, or already consumed.

LEASE_EXPIREDdo not blind-retry

The current epoch lease expired; a recovery or new claim is required.

STALE_FENCEdo not blind-retry

This write came from a fence generation that is no longer current.

SEQUENCE_GAPdo not blind-retry

The submitted sequence number is not the expected next value.

CONFLICTING_IDEMPOTENCY_REPLAYdo not blind-retry

The idempotency key was already used with different arguments.

QUESTION_OPENsafe to retry

A durable question is open and awaiting an accepted answer.

QUESTION_DELIVERY_DEGRADEDsafe to retry

A notification channel is degraded; the canonical inbox record is unaffected.

QUESTION_RESPONSE_DEADLINE_EXCEEDEDsafe to retryneeds operator action

The response deadline passed with no accepted answer; the question stays open.

BRIEF_VERSION_CONFLICTdo not blind-retryneeds operator action

The pinned brief base moved before finalization.

RUN_ALREADY_TERMINALdo not blind-retry

The run is already terminal; read review_status — there is nothing to cancel.

CANCELLEDdo not blind-retry

This session was cancelled; no further mutation can complete it.

PAYLOAD_REJECTEDdo not blind-retry

The payload violated a bound, forbidden field, or content rule.

VALIDATION_FAILEDdo not blind-retry

The submitted result failed a repairable schema/evidence/prerequisite rule.

CONTEXT_FORBIDDENdo not blind-retryneeds operator action

The caller's scope or project grant does not reach this context source.

CONTEXT_UNAVAILABLEsafe to retry

The requested context source or citation could not be resolved.

Invalid calls and exact recovery

These deterministic fixtures preserve the actual boundary distinction: authenticated domain failures are MCP result.isError responses with matching text and structured bodies, while a rejected credential stops at the HTTP 401 challenge before any tool runs. Example IDs and timestamps are inert fixtures.

Missing scope

Call local review origination without review:execute.

Invalid call · review_start
{
  "toolName": "review_start",
  "arguments": {
    "briefId": "brf_fixture_checkout",
    "execution": "local",
    "idempotencyKey": "review-start-local-v1"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"forbidden\",\"message\":\"this action requires the review:execute scope\",\"details\":{\"reason\":\"AUTHORIZATION_SCOPE_MISSING\",\"missingScope\":\"review:execute\",\"repair\":\"request_additional_scope\"},\"retryable\":false,\"requestId\":\"req_fixture_scope\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "forbidden",
        "message": "this action requires the review:execute scope",
        "details": {
          "reason": "AUTHORIZATION_SCOPE_MISSING",
          "missingScope": "review:execute",
          "repair": "request_additional_scope"
        },
        "retryable": false,
        "requestId": "req_fixture_scope"
      }
    },
    "isError": true
  }
}

Correction: A human grants only review:execute through delegated consent or agent-token configuration; reload the session and repeat the same logical mutation.

Malformed input or cross-field refinement

Omit both identifiers required by review_execution_status.

Invalid call · review_execution_status
{
  "toolName": "review_execution_status",
  "arguments": {}
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"validation\",\"message\":\"invalid arguments for review_execution_status: reviewSessionId or executionId is required\",\"details\":{\"issues\":[{\"code\":\"custom\",\"message\":\"reviewSessionId or executionId is required\",\"path\":[]}]},\"retryable\":false,\"requestId\":\"req_fixture_validation\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "validation",
        "message": "invalid arguments for review_execution_status: reviewSessionId or executionId is required",
        "details": {
          "issues": [
            {
              "code": "custom",
              "message": "reviewSessionId or executionId is required",
              "path": []
            }
          ]
        },
        "retryable": false,
        "requestId": "req_fixture_validation"
      }
    },
    "isError": true
  }
}

Correction: Supply one authoritative identifier returned by the claim or session status.

Corrective call · review_execution_status
{
  "executionId": "xex_fixture_engineering"
}

Conflicting idempotency replay

Reuse a checkpoint idempotency key with changed receipt arguments.

Invalid call · review_execution_checkpoint_append
{
  "toolName": "review_execution_checkpoint_append",
  "arguments": {
    "executionId": "xex_fixture_engineering",
    "fenceGeneration": 3,
    "seq": 3,
    "milestoneName": "validation_result",
    "safeSummary": "Changed payload.",
    "idempotencyKey": "checkpoint-3-original"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"conflict\",\"message\":\"The idempotency key was already used with different arguments.\",\"details\":{\"state\":{\"sessionState\":\"running\",\"executionId\":\"xex_fixture_engineering\",\"epoch\":3,\"protocolVersion\":\"1.1\",\"bundleVersion\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"allowedNextOperations\":[{\"operation\":\"review_execution_sync\",\"preconditions\":[\"Follow the current server control block.\"]}],\"completion\":{\"complete\":false,\"unmetRequirements\":[\"The execution has not reached a terminal accepted submit.\"],\"certificateState\":\"not_applicable\"},\"progress\":{\"checkpointHighWaterMark\":2,\"openQuestionCount\":0,\"leaseExpiresAt\":\"2026-09-07T18:15:00.000Z\",\"suggestedPollAt\":\"2026-09-07T18:05:00.000Z\"},\"operatorAction\":{\"required\":false},\"error\":{\"code\":\"CONFLICTING_IDEMPOTENCY_REPLAY\",\"retryable\":false,\"currentState\":\"running\",\"permittedNextOperations\":[\"review_execution_sync\"],\"safeText\":\"The idempotency key was already used with different arguments.\"}},\"retryable\":false,\"requestId\":\"req_fixture_idempotency\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "conflict",
        "message": "The idempotency key was already used with different arguments.",
        "details": {
          "state": {
            "sessionState": "running",
            "executionId": "xex_fixture_engineering",
            "epoch": 3,
            "protocolVersion": "1.1",
            "bundleVersion": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          },
          "allowedNextOperations": [
            {
              "operation": "review_execution_sync",
              "preconditions": [
                "Follow the current server control block."
              ]
            }
          ],
          "completion": {
            "complete": false,
            "unmetRequirements": [
              "The execution has not reached a terminal accepted submit."
            ],
            "certificateState": "not_applicable"
          },
          "progress": {
            "checkpointHighWaterMark": 2,
            "openQuestionCount": 0,
            "leaseExpiresAt": "2026-09-07T18:15:00.000Z",
            "suggestedPollAt": "2026-09-07T18:05:00.000Z"
          },
          "operatorAction": {
            "required": false
          },
          "error": {
            "code": "CONFLICTING_IDEMPOTENCY_REPLAY",
            "retryable": false,
            "currentState": "running",
            "permittedNextOperations": [
              "review_execution_sync"
            ],
            "safeText": "The idempotency key was already used with different arguments."
          }
        },
        "retryable": false,
        "requestId": "req_fixture_idempotency"
      }
    },
    "isError": true
  }
}

Correction: Read status and receipts. Replay the original unchanged arguments with the original key, or use a fresh key only for a new logical checkpoint.

Corrective call · review_execution_status
{
  "executionId": "xex_fixture_engineering"
}

Brief version conflict

Replace a brief using a stale ifVersionNum.

Invalid call · brief_update
{
  "toolName": "brief_update",
  "arguments": {
    "briefId": "brf_fixture_checkout",
    "content": {},
    "ifVersionNum": 4,
    "idempotencyKey": "brief-update-v4"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"conflict\",\"message\":\"brief moved to a newer version since you loaded it — reload and retry\",\"details\":{\"reason\":\"BRIEF_VERSION_CONFLICT\",\"ifVersionNum\":4,\"currentVersionNum\":5},\"retryable\":false,\"requestId\":\"req_fixture_brief_version\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "conflict",
        "message": "brief moved to a newer version since you loaded it — reload and retry",
        "details": {
          "reason": "BRIEF_VERSION_CONFLICT",
          "ifVersionNum": 4,
          "currentVersionNum": 5
        },
        "retryable": false,
        "requestId": "req_fixture_brief_version"
      }
    },
    "isError": true
  }
}

Correction: Reread the full brief, preserve every untouched key, reconcile the human-visible conflict, and use a new mutation key for the changed replacement.

Corrective call · brief_get_full
{
  "briefId": "brf_fixture_checkout"
}

Stale execution fence

Heartbeat with a fence generation superseded by a handoff or recovery claim.

Invalid call · review_execution_heartbeat
{
  "toolName": "review_execution_heartbeat",
  "arguments": {
    "executionId": "xex_fixture_engineering",
    "fenceGeneration": 2,
    "idempotencyKey": "heartbeat-stale-fence"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"conflict\",\"message\":\"This write came from fence generation 2; the current generation is 3.\",\"details\":{\"state\":{\"sessionState\":\"running\",\"executionId\":\"xex_fixture_engineering\",\"epoch\":3,\"protocolVersion\":\"1.1\",\"bundleVersion\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"allowedNextOperations\":[{\"operation\":\"review_execution_status\",\"preconditions\":[\"Follow the current server control block.\"]}],\"completion\":{\"complete\":false,\"unmetRequirements\":[\"The execution has not reached a terminal accepted submit.\"],\"certificateState\":\"not_applicable\"},\"progress\":{\"checkpointHighWaterMark\":2,\"openQuestionCount\":0,\"leaseExpiresAt\":\"2026-09-07T18:15:00.000Z\",\"suggestedPollAt\":\"2026-09-07T18:05:00.000Z\"},\"operatorAction\":{\"required\":false},\"error\":{\"code\":\"STALE_FENCE\",\"retryable\":false,\"currentState\":\"running\",\"permittedNextOperations\":[\"review_execution_status\"],\"safeText\":\"This write came from fence generation 2; the current generation is 3.\"}},\"retryable\":false,\"requestId\":\"req_fixture_stale_fence\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "conflict",
        "message": "This write came from fence generation 2; the current generation is 3.",
        "details": {
          "state": {
            "sessionState": "running",
            "executionId": "xex_fixture_engineering",
            "epoch": 3,
            "protocolVersion": "1.1",
            "bundleVersion": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          },
          "allowedNextOperations": [
            {
              "operation": "review_execution_status",
              "preconditions": [
                "Follow the current server control block."
              ]
            }
          ],
          "completion": {
            "complete": false,
            "unmetRequirements": [
              "The execution has not reached a terminal accepted submit."
            ],
            "certificateState": "not_applicable"
          },
          "progress": {
            "checkpointHighWaterMark": 2,
            "openQuestionCount": 0,
            "leaseExpiresAt": "2026-09-07T18:15:00.000Z",
            "suggestedPollAt": "2026-09-07T18:05:00.000Z"
          },
          "operatorAction": {
            "required": false
          },
          "error": {
            "code": "STALE_FENCE",
            "retryable": false,
            "currentState": "running",
            "permittedNextOperations": [
              "review_execution_status"
            ],
            "safeText": "This write came from fence generation 2; the current generation is 3."
          }
        },
        "retryable": false,
        "requestId": "req_fixture_stale_fence"
      }
    },
    "isError": true
  }
}

Correction: Discard the local fence and inspect the authoritative execution before any mutation.

Corrective call · review_execution_status
{
  "executionId": "xex_fixture_engineering"
}

Expired execution lease

Heartbeat after the current epoch lease has expired.

Invalid call · review_execution_heartbeat
{
  "toolName": "review_execution_heartbeat",
  "arguments": {
    "executionId": "xex_fixture_engineering",
    "fenceGeneration": 3,
    "idempotencyKey": "heartbeat-expired-lease"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"conflict\",\"message\":\"The current epoch lease already expired; reclaim via review_execution_claim.\",\"details\":{\"state\":{\"sessionState\":\"running\",\"executionId\":\"xex_fixture_engineering\",\"epoch\":3,\"protocolVersion\":\"1.1\",\"bundleVersion\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"allowedNextOperations\":[{\"operation\":\"review_execution_claim\",\"preconditions\":[\"Follow the current server control block.\"]}],\"completion\":{\"complete\":false,\"unmetRequirements\":[\"The execution has not reached a terminal accepted submit.\"],\"certificateState\":\"not_applicable\"},\"progress\":{\"checkpointHighWaterMark\":2,\"openQuestionCount\":0,\"leaseExpiresAt\":\"2026-09-07T17:55:00.000Z\",\"suggestedPollAt\":\"2026-09-07T18:05:00.000Z\"},\"operatorAction\":{\"required\":false},\"error\":{\"code\":\"LEASE_EXPIRED\",\"retryable\":false,\"currentState\":\"running\",\"permittedNextOperations\":[\"review_execution_claim\"],\"safeText\":\"The current epoch lease already expired; reclaim via review_execution_claim.\"}},\"retryable\":false,\"requestId\":\"req_fixture_expired_lease\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "conflict",
        "message": "The current epoch lease already expired; reclaim via review_execution_claim.",
        "details": {
          "state": {
            "sessionState": "running",
            "executionId": "xex_fixture_engineering",
            "epoch": 3,
            "protocolVersion": "1.1",
            "bundleVersion": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          },
          "allowedNextOperations": [
            {
              "operation": "review_execution_claim",
              "preconditions": [
                "Follow the current server control block."
              ]
            }
          ],
          "completion": {
            "complete": false,
            "unmetRequirements": [
              "The execution has not reached a terminal accepted submit."
            ],
            "certificateState": "not_applicable"
          },
          "progress": {
            "checkpointHighWaterMark": 2,
            "openQuestionCount": 0,
            "leaseExpiresAt": "2026-09-07T17:55:00.000Z",
            "suggestedPollAt": "2026-09-07T18:05:00.000Z"
          },
          "operatorAction": {
            "required": false
          },
          "error": {
            "code": "LEASE_EXPIRED",
            "retryable": false,
            "currentState": "running",
            "permittedNextOperations": [
              "review_execution_claim"
            ],
            "safeText": "The current epoch lease already expired; reclaim via review_execution_claim."
          }
        },
        "retryable": false,
        "requestId": "req_fixture_expired_lease"
      }
    },
    "isError": true
  }
}

Correction: Read status, then follow only the returned recovery or fresh human-grant claim path.

Corrective call · review_execution_status
{
  "executionId": "xex_fixture_engineering"
}

Review configuration missing

Start the first review for a project with no configured AI reviewer.

Invalid call · review_start
{
  "toolName": "review_start",
  "arguments": {
    "briefId": "brf_fixture_checkout",
    "idempotencyKey": "review-start-configless"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"validation\",\"message\":\"configure at least one AI reviewer in the portal before starting the first review pass\",\"retryable\":false,\"requestId\":\"req_fixture_configless\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "validation",
        "message": "configure at least one AI reviewer in the portal before starting the first review pass",
        "retryable": false,
        "requestId": "req_fixture_configless"
      }
    },
    "isError": true
  }
}

Correction: A human configures at least one project reviewer/provider/model in the Semel portal; then the agent retries review_start with a new logical-attempt key.

Pinned artifact publication missing

Fetch a pinned active skill whose exact role/version/hash row or bytes are unavailable.

Invalid call · review_execution_skill_get
{
  "toolName": "review_execution_skill_get",
  "arguments": {
    "executionId": "xex_fixture_engineering",
    "role": "engineering"
  }
}
MCP JSON-RPC error result
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":{\"kind\":\"not_found\",\"message\":\"the pinned engineering skill artifact is unavailable for this execution\",\"details\":{\"state\":{\"sessionState\":\"running\",\"executionId\":\"xex_fixture_engineering\",\"epoch\":3,\"protocolVersion\":\"1.1\",\"bundleVersion\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"allowedNextOperations\":[{\"operation\":\"review_execution_status\",\"preconditions\":[\"Follow the current server control block.\"]}],\"completion\":{\"complete\":false,\"unmetRequirements\":[\"The execution has not reached a terminal accepted submit.\"],\"certificateState\":\"not_applicable\"},\"progress\":{\"checkpointHighWaterMark\":2,\"openQuestionCount\":0,\"leaseExpiresAt\":\"2026-09-07T18:15:00.000Z\",\"suggestedPollAt\":\"2026-09-07T18:05:00.000Z\"},\"operatorAction\":{\"required\":false},\"error\":{\"code\":\"PAYLOAD_REJECTED\",\"retryable\":false,\"currentState\":\"running\",\"permittedNextOperations\":[\"review_execution_status\"],\"safeText\":\"the pinned engineering skill artifact is unavailable for this execution\"}},\"retryable\":false,\"requestId\":\"req_fixture_publication\"}}"
      }
    ],
    "structuredContent": {
      "error": {
        "kind": "not_found",
        "message": "the pinned engineering skill artifact is unavailable for this execution",
        "details": {
          "state": {
            "sessionState": "running",
            "executionId": "xex_fixture_engineering",
            "epoch": 3,
            "protocolVersion": "1.1",
            "bundleVersion": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          },
          "allowedNextOperations": [
            {
              "operation": "review_execution_status",
              "preconditions": [
                "Follow the current server control block."
              ]
            }
          ],
          "completion": {
            "complete": false,
            "unmetRequirements": [
              "The execution has not reached a terminal accepted submit."
            ],
            "certificateState": "not_applicable"
          },
          "progress": {
            "checkpointHighWaterMark": 2,
            "openQuestionCount": 0,
            "leaseExpiresAt": "2026-09-07T18:15:00.000Z",
            "suggestedPollAt": "2026-09-07T18:05:00.000Z"
          },
          "operatorAction": {
            "required": false
          },
          "error": {
            "code": "PAYLOAD_REJECTED",
            "retryable": false,
            "currentState": "running",
            "permittedNextOperations": [
              "review_execution_status"
            ],
            "safeText": "the pinned engineering skill artifact is unavailable for this execution"
          }
        },
        "retryable": false,
        "requestId": "req_fixture_publication"
      }
    },
    "isError": true
  }
}

Correction: Stop execution and ask an operator to publish the exact pinned role/version/hash. Check status after publication; never substitute latest bytes.

Corrective call · review_execution_status
{
  "executionId": "xex_fixture_engineering"
}

Revoked or rejected login

Initialize MCP with a bearer credential the server evaluated and rejected.

Rejected HTTP request
{
  "method": "POST",
  "url": "https://mcp.semel.ai/mcp",
  "bearer": "<redacted rejected credential>"
}
HTTP authentication challenge
{
  "status": 401,
  "headers": {
    "cache-control": "no-store",
    "www-authenticate": "Bearer resource_metadata=\"https://mcp.semel.ai/.well-known/oauth-protected-resource/mcp\", error=\"invalid_token\""
  }
}

Correction: Stop concurrent clients sharing the credential, complete one harness-native login, reload the session, and require live initialize plus tools/list before continuing.

Grants, leases, and lost sessions

Call review_execution_status, then review_execution_sync, before recovery. GRANT_REQUIRED / GRANT_EXPIRED: create a grant request if permitted and wait for a human to approve a fresh grant. LEASE_EXPIRED / STALE_FENCE: stop mutating with the old claim and follow the returned legal claim path. SEQUENCE_GAP: synchronize and send exactly the next sequence; never skip or renumber history. RUN_ALREADY_TERMINAL / CANCELLED: read final status and stop. Do not create duplicate reviews, sessions, or epochs.

Questions and notification delivery

QUESTION_OPEN means execution is waiting for an accepted human answer; poll/read status without inventing one. QUESTION_DELIVERY_DEGRADED means Slack/email delivery is impaired while the canonical Semel inbox record remains valid; direct the human to Semel. QUESTION_RESPONSE_DEADLINE_EXCEEDED leaves the question open and may supply an operator URI; a person decides the response or recovery.

Context and export failures

CONTEXT_UNAVAILABLE is retryable only as the returned control block permits; relist sources and search again rather than guessing a citation. If brief_export_package fails, no implementation-ready package exists. Repair the reported brief/export condition and retry with the correct idempotency behavior; do not fall back to deprecated brief_export_markdown as a verified handoff.

Installer and update recovery

Unknown release key, invalid Ed25519 signature, identity/hash mismatch, incompatible protocol, malformed skill metadata, or a non-HTTPS artifact URL must stop installation. Keep the prior copy. failed_restored means the old verified copy was restored; inspect the reason before retrying. failed_restore reports backup paths and needs manual operator restoration. A custom local file is refused unless the operator has preserved changes and deliberately chooses --allow-custom.