{
  "schemaVersion": 2,
  "generated": "2026-10-10",
  "source": "https://octopusprimeai.com/ai/errors.json",
  "html": "https://octopusprimeai.com/ai/errors",
  "appliesTo": "Octopus Prime channel plugin 1.1.0 · OpenClaw ≥ 2026.9.8",
  "lastVerified": "2026-10-10",
  "description": "Exact texts shown by Octopus Prime, its channel plugin and the apps, with where they appear, cause, fix and how to verify recovery. Texts are verbatim: placeholders in <angle brackets> or {braces}.",
  "fields": {
    "id": "Stable identifier: lower case, words joined by \"-\" (delivery failure reasons keep their own value, e.g. \"ack_timeout\"). Never reused.",
    "component": "One of: plugin-setup, plugin-runtime, connection-close-code, delivery-failure, service-http, app-ui.",
    "text": "Exact text as the product shows it, copied verbatim. Placeholders in <angle brackets> or {braces}.",
    "where": "Where the text appears.",
    "cause": "What causes it.",
    "fix": "What to do.",
    "verify": "How to confirm the fix worked (\"—\" when there is nothing to check)."
  },
  "components": {
    "plugin-setup": "Printed by `openclaw channels add --channel octopus-prime` during setup.",
    "plugin-runtime": "Gateway log lines, plugin rejection reasons and `openclaw channels status` errors while the plugin runs.",
    "connection-close-code": "WebSocket close codes of the plugin connection to the Octopus Prime service.",
    "delivery-failure": "Reason values behind a FAILED, expired or cancelled delivery chip.",
    "service-http": "HTTP `detail` texts returned by the Octopus Prime service.",
    "app-ui": "Banners, toasts and inline messages in the web and mobile apps."
  },
  "count": 250,
  "errors": [
    {
      "id": "setup-code-required",
      "component": "plugin-setup",
      "text": "Octopus Prime setup code is required",
      "where": "Output of openclaw channels add --channel octopus-prime",
      "cause": "The command ran without --setup-code.",
      "fix": "Create a code in the web app (OpenClaw Agents → Connect OpenClaw, or New setup code) and run openclaw channels add --channel octopus-prime --backend-url 'https://api.octopusprimeai.com' --setup-code <code>",
      "verify": "The command finishes without error and the connector leaves SETUP REQUIRED."
    },
    {
      "id": "bootstrap-failed",
      "component": "plugin-setup",
      "text": "Octopus Prime AI bootstrap failed (<HTTP status>): <server body>",
      "where": "Output of openclaw channels add; <server body> is the service's JSON, for example {\"detail\":\"Invalid or used setup code\"}",
      "cause": "The setup-code exchange (POST /api/connector/bootstrap) was refused. Read the detail: 404 Invalid or used setup code, 410 Setup code expired, 404 Connector not found, 404 Connector revoked, 409 Organization is archived, 426 Unsupported OpenClaw plugin API <v>. Supported: ['2026.9.7'].",
      "fix": "Fix by detail (see the service errors for the bootstrap endpoint): new code for used/expired codes; Connect OpenClaw again for a missing or revoked connector; an Owner restores an archived organization; install the plugin package Octopus Prime provides for 426.",
      "verify": "Rerun succeeds; the connector moves from SETUP REQUIRED to CONNECTING."
    },
    {
      "id": "bootstrap-incomplete",
      "component": "plugin-setup",
      "text": "Octopus Prime AI bootstrap returned an incomplete connector credential",
      "where": "Output of openclaw channels add",
      "cause": "The exchange answered successfully but without the credential or identifiers (service or proxy problem). Nothing was written.",
      "fix": "Retry with a new setup code after a few minutes; check that no proxy rewrites HTTPS responses; if it repeats, contact support with openclaw triage --non-interactive output.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "bootstrap-invalid-connector-identity",
      "component": "plugin-setup",
      "text": "Octopus Prime requires a valid authenticated connector identity",
      "where": "Output of openclaw channels add",
      "cause": "The exchange returned an invalid connector id.",
      "fix": "Same as the incomplete-credential case: retry with a new code; contact support if it repeats.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "bootstrap-invalid-org-identity",
      "component": "plugin-setup",
      "text": "Octopus Prime requires a valid authenticated organization identity",
      "where": "Output of openclaw channels add",
      "cause": "The exchange returned an invalid organization id.",
      "fix": "Retry with a new code; contact support if it repeats.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "backend-identity-mismatch",
      "component": "plugin-setup",
      "text": "Octopus Prime AI bootstrap backend identity does not match the requested canonical backend",
      "where": "Output of openclaw channels add",
      "cause": "The backend that answered is not the one named in --backend-url (wrong URL, or a redirect or proxy in between).",
      "fix": "Use exactly --backend-url 'https://api.octopusprimeai.com' and make sure nothing redirects it.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "invalid-origin-url",
      "component": "plugin-setup",
      "text": "Invalid ingress origin URL",
      "where": "Output of openclaw channels add",
      "cause": "--backend-url is not a valid URL.",
      "fix": "Use exactly 'https://api.octopusprimeai.com'.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "origin-requires-https",
      "component": "plugin-setup",
      "text": "Ingress origin requires a secure HTTPS URL without credentials, query or fragment",
      "where": "Output of openclaw channels add",
      "cause": "--backend-url is not https:// or contains user:password@, ?query or #fragment.",
      "fix": "Use exactly 'https://api.octopusprimeai.com'.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "default-account-only",
      "component": "plugin-setup",
      "text": "Octopus Prime supports the default connector account only",
      "where": "Output of openclaw channels add",
      "cause": "--account was given with a value other than the default account.",
      "fix": "Remove --account. One Gateway (OpenClaw profile) connects to one organization; use a separate profile or Gateway for another organization.",
      "verify": "Rerun succeeds."
    },
    {
      "id": "exchange-required",
      "component": "plugin-setup",
      "text": "Octopus Prime setup must complete authenticated connector exchange before configuration is written",
      "where": "Output of openclaw channels add",
      "cause": "Setup was asked to write config without a successful code exchange (for example only --connector-token, --connector-id or --org-id were passed).",
      "fix": "Run setup with --setup-code: openclaw channels add --channel octopus-prime --backend-url 'https://api.octopusprimeai.com' --setup-code <code>",
      "verify": "Rerun succeeds; channels.octopus-prime is written."
    },
    {
      "id": "setup-network-error",
      "component": "plugin-setup",
      "text": "DNS, TLS or timeout error during setup (text comes from the operating system or runtime)",
      "where": "Output of openclaw channels add",
      "cause": "The Gateway host cannot reach https://api.octopusprimeai.com (no outbound HTTPS, DNS, firewall or proxy problem).",
      "fix": "Fix outbound HTTPS from the Gateway host, then rerun setup (with a new code if 15 minutes have passed).",
      "verify": "curl -sS https://api.octopusprimeai.com/api/health/live prints {\"status\":\"live\"}."
    },
    {
      "id": "socket-closed",
      "component": "plugin-runtime",
      "text": "octopus-prime connector socket closed (code <N>); reconnecting in <n> seconds",
      "where": "Gateway log (warning); openclaw channels logs --channel octopus-prime",
      "cause": "The connection to the service closed with close code N; n is the backoff (2, 4, 8, then 15 s).",
      "fix": "Look up N under Connection close codes (4401, 4403, 4426, 1002, 1001, 1011, 1012). Occasional 1006 or 1012 lines are normal; a repeating code is not.",
      "verify": "The line stops repeating and the connector shows READY."
    },
    {
      "id": "socket-silent",
      "component": "plugin-runtime",
      "text": "octopus-prime connector socket was silent for 50 seconds; reconnecting in <n> seconds",
      "where": "Gateway log",
      "cause": "No frame arrived for 50 s (network drop, sleeping host, or a proxy that kills idle or long-lived WebSockets).",
      "fix": "Usually recovers by itself. If it repeats, check outbound WSS stability, proxy idle timeouts and host sleep settings.",
      "verify": "No new lines; connector READY."
    },
    {
      "id": "socket-not-created",
      "component": "plugin-runtime",
      "text": "octopus-prime connector socket could not be created; reconnecting in <n> seconds",
      "where": "Gateway log",
      "cause": "The WebSocket could not be opened (bad backendUrl or no network).",
      "fix": "Check channels.octopus-prime.backendUrl is https://api.octopusprimeai.com and outbound WSS is allowed.",
      "verify": "Connector READY."
    },
    {
      "id": "config-issue-run-setup",
      "component": "plugin-runtime",
      "text": "<issue>. Run Octopus Prime setup, then restart this channel account.",
      "where": "error field of openclaw channels status (account inspect); issue is one of: Octopus Prime requires a resolved connector credential · Octopus Prime requires a canonical HTTPS backend URL · Octopus Prime requires a valid connector identity pin · Octopus Prime requires a valid organization identity pin",
      "cause": "channels.octopus-prime is missing or invalid: no connectorToken (or a SecretRef that does not resolve), a non-canonical backendUrl, or invalid connectorId/orgId.",
      "fix": "Create a new setup code and rerun setup. For a SecretRef credential, fix the secret source and run openclaw secrets reload.",
      "verify": "tokenStatus: \"available\" and statusState: \"ready\" in openclaw channels status --probe --channel octopus-prime --json."
    },
    {
      "id": "pin-changed-restart",
      "component": "plugin-runtime",
      "text": "Connector pin changed; restart the Octopus Prime channel account to activate the new identity generation",
      "where": "openclaw channels status (statusState restart-required)",
      "cause": "connectorId or orgId changed while the account was running (after setup with a code for a different connector).",
      "fix": "openclaw gateway restart (add --safe to wait for active work).",
      "verify": "statusState: \"ready\"; connector READY."
    },
    {
      "id": "identity-pin-mismatch",
      "component": "plugin-runtime",
      "text": "Authenticated connector does not match the configured connector identity pin",
      "where": "openclaw channels status (statusState error; transport stopped)",
      "cause": "The credential belongs to a different connector than connectorId, usually because config from two setups was mixed or copied.",
      "fix": "Create a new setup code for the intended connector and rerun setup; do not hand-edit connectorId, orgId or connectorToken.",
      "verify": "statusState: \"ready\"."
    },
    {
      "id": "generation-changed",
      "component": "plugin-runtime",
      "text": "Authenticated connector changed within an active ingress generation",
      "where": "Gateway log or channels status",
      "cause": "Config identity changed under a running connection.",
      "fix": "Restart after config changes: openclaw gateway restart.",
      "verify": "Connector READY."
    },
    {
      "id": "ingress-origin-mismatch",
      "component": "plugin-runtime",
      "text": "Current configuration does not match the authenticated ingress origin",
      "where": "Gateway log or channels status",
      "cause": "backendUrl or ids were edited while the connection was running.",
      "fix": "openclaw gateway restart; prefer rerunning setup over hand edits.",
      "verify": "Connector READY."
    },
    {
      "id": "outbound-origin-mismatch",
      "component": "plugin-runtime",
      "text": "Current configuration no longer matches the authenticated outbound origin",
      "where": "Gateway log or channels status",
      "cause": "Config was edited while replies were being sent.",
      "fix": "openclaw gateway restart.",
      "verify": "Connector READY."
    },
    {
      "id": "outbound-generation-stale",
      "component": "plugin-runtime",
      "text": "Connector outbound readiness generation is no longer current",
      "where": "Gateway log or channels status",
      "cause": "The connection restarted while a reply was pending.",
      "fix": "Usually transient; if it persists, openclaw gateway restart.",
      "verify": "Replies arrive."
    },
    {
      "id": "negotiated-contract-mismatch",
      "component": "plugin-runtime",
      "text": "Backend did not return the exact negotiated connector contract",
      "where": "Gateway log (octopus-prime inbound error: …); the plugin closes the connection with 1002 protocol-error",
      "cause": "Protocol mismatch between plugin and service, or a proxy altering WebSocket traffic.",
      "fix": "Install the plugin package Octopus Prime currently provides; bypass WebSocket-inspecting proxies; contact support if it persists.",
      "verify": "Reconnect succeeds; connector READY."
    },
    {
      "id": "welcome-not-object",
      "component": "plugin-runtime",
      "text": "Protocol welcome is not an object",
      "where": "Gateway log (octopus-prime inbound error: …); closes 1002",
      "cause": "Unexpected frame from the service or a proxy.",
      "fix": "As above.",
      "verify": "Reconnect succeeds."
    },
    {
      "id": "data-before-negotiation",
      "component": "plugin-runtime",
      "text": "Backend sent application data before protocol negotiation completed",
      "where": "Gateway log (octopus-prime inbound error: …); closes 1002",
      "cause": "Protocol order violated (version mismatch or proxy).",
      "fix": "As above.",
      "verify": "Reconnect succeeds."
    },
    {
      "id": "frame-not-object",
      "component": "plugin-runtime",
      "text": "Connector frame is not an object",
      "where": "Gateway log (octopus-prime inbound error: …); closes 1002 (invalid JSON closes 1002 invalid-json)",
      "cause": "Malformed frame.",
      "fix": "As above.",
      "verify": "Reconnect succeeds."
    },
    {
      "id": "agent-not-announced",
      "component": "plugin-runtime",
      "text": "Agent is not currently announced by this connector",
      "where": "Sent by the plugin as a rejection reason; the message's chip becomes FAILED (last_error connector_rejected)",
      "cause": "Octopus Prime targeted an agent id that this Gateway no longer has (agent removed or renamed id in OpenClaw).",
      "fix": "Restore the agent in OpenClaw (openclaw agents list) or message an agent that exists. New messages deliver once the agent is announced again.",
      "verify": "A new message reaches RESPONDED."
    },
    {
      "id": "inbound-missing-facts",
      "component": "plugin-runtime",
      "text": "Inbound message is missing stable event, channel, agent, sender, or body facts",
      "where": "Plugin rejection reason; chip FAILED",
      "cause": "Malformed delivery from the service.",
      "fix": "Contact support with the time and conversation; include openclaw triage --non-interactive output.",
      "verify": "—"
    },
    {
      "id": "inbound-thread-invalid",
      "component": "plugin-runtime",
      "text": "Inbound thread id is invalid",
      "where": "Plugin rejection reason; chip FAILED",
      "cause": "Malformed delivery.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "inbound-sender-invalid",
      "component": "plugin-runtime",
      "text": "Inbound sender name is invalid",
      "where": "Plugin rejection reason; chip FAILED",
      "cause": "Malformed delivery.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "inbound-timestamp-invalid",
      "component": "plugin-runtime",
      "text": "Inbound timestamp is invalid",
      "where": "Plugin rejection reason; chip FAILED",
      "cause": "Malformed delivery.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "inbound-frame-not-object",
      "component": "plugin-runtime",
      "text": "Inbound frame is not an object",
      "where": "Plugin rejection reason; chip FAILED",
      "cause": "Malformed delivery.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "target-agent-not-configured",
      "component": "plugin-runtime",
      "text": "Octopus target agent is not currently configured",
      "where": "Dispatch error in the Gateway log",
      "cause": "The delivery names an agent id that is not in the Gateway's agent list.",
      "fix": "Add or restore the agent in OpenClaw (openclaw agents list), or use another agent in Octopus Prime.",
      "verify": "A new message reaches RESPONDED."
    },
    {
      "id": "account-disabled",
      "component": "plugin-runtime",
      "text": "Octopus connector account is disabled",
      "where": "Dispatch error",
      "cause": "channels.octopus-prime.enabled is false.",
      "fix": "openclaw plugins enable octopus-prime and/or set channels.octopus-prime.enabled back to true.",
      "verify": "Connector READY."
    },
    {
      "id": "account-unavailable",
      "component": "plugin-runtime",
      "text": "Octopus connector account is unavailable",
      "where": "Dispatch error",
      "cause": "A non-default OpenClaw account was addressed.",
      "fix": "Use only the default account; remove any accounts config for octopus-prime.",
      "verify": "Connector READY."
    },
    {
      "id": "core-did-not-dispatch",
      "component": "plugin-runtime",
      "text": "OpenClaw did not dispatch admitted Octopus event <event_id>",
      "where": "Gateway log",
      "cause": "OpenClaw core declined to run the agent turn (agent configuration, model or provider error).",
      "fix": "Read openclaw logs --follow around that time; fix the agent or model configuration; ask the person to send the message again.",
      "verify": "Chip goes WORKING then RESPONDED."
    },
    {
      "id": "working-not-sent",
      "component": "plugin-runtime",
      "text": "octopus-prime Working status could not be sent",
      "where": "Gateway log",
      "cause": "The connection dropped during a turn.",
      "fix": "Transient; check connectivity if frequent.",
      "verify": "—"
    },
    {
      "id": "outbound-failed",
      "component": "plugin-runtime",
      "text": "octopus-prime outbound delivery failed: <error>",
      "where": "Gateway log",
      "cause": "Sending a reply failed; OpenClaw core retries it (on 2026.9.8 up to 5 attempts, 5 s to 10 min apart).",
      "fix": "Read the inner <error> (entries below).",
      "verify": "The reply appears; chip RESPONDED."
    },
    {
      "id": "send-receipt-timeout",
      "component": "plugin-runtime",
      "text": "Timed out waiting for backend send receipt",
      "where": "Inner error of octopus-prime outbound delivery failed",
      "cause": "No receipt within 20 s. Includes the case where the agent was removed from the conversation or the conversation was archived (the service ignores the reply).",
      "fix": "Check the agent is still in the conversation and the conversation is active; otherwise check the connection.",
      "verify": "Next reply appears."
    },
    {
      "id": "status-receipt-timeout",
      "component": "plugin-runtime",
      "text": "Timed out waiting for backend status receipt",
      "where": "Inner error",
      "cause": "Same as the send-receipt timeout.",
      "fix": "Same as above.",
      "verify": "Next reply appears."
    },
    {
      "id": "outbound-not-ready",
      "component": "plugin-runtime",
      "text": "Connector is not ready with a current authenticated and explicitly pinned outbound origin",
      "where": "Inner error",
      "cause": "A reply was attempted while the connection was down for more than 30 s.",
      "fix": "Restore connectivity; OpenClaw core retries.",
      "verify": "Reply appears after reconnect."
    },
    {
      "id": "closed-before-receipt",
      "component": "plugin-runtime",
      "text": "Connector socket closed before backend receipt",
      "where": "Inner error",
      "cause": "The connection dropped while sending.",
      "fix": "Transient; OpenClaw core retries.",
      "verify": "Reply appears."
    },
    {
      "id": "stopped-before-receipt",
      "component": "plugin-runtime",
      "text": "Connector transport stopped before backend receipt",
      "where": "Inner error",
      "cause": "The channel stopped (restart, disable) while sending.",
      "fix": "Transient; OpenClaw core retries.",
      "verify": "Reply appears."
    },
    {
      "id": "outbound-rejected",
      "component": "plugin-runtime",
      "text": "Backend rejected outbound intent: <reason>",
      "where": "Inner error, permanent (not retried)",
      "cause": "reason source_expired: the triggering message is older than the 30-day window; channel_unavailable: the conversation is no longer available to the agent; identity_conflict: the same reply id was reused with different text.",
      "fix": "Nothing to retry for source_expired; for channel_unavailable re-add the agent or use an active conversation; identity_conflict indicates a bug: contact support.",
      "verify": "—"
    },
    {
      "id": "receipt-missing-identity",
      "component": "plugin-runtime",
      "text": "Backend outbound receipt omitted message identity",
      "where": "Inner error",
      "cause": "Unexpected service response.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "invalid-status-receipt",
      "component": "plugin-runtime",
      "text": "Backend returned an invalid outbound status receipt",
      "where": "Inner error",
      "cause": "Unexpected service response.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "intent-not-accepted",
      "component": "plugin-runtime",
      "text": "Backend did not accept outbound intent",
      "where": "Inner error",
      "cause": "Unexpected service response.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "reply-connector-changed",
      "component": "plugin-runtime",
      "text": "The Octopus Prime reply connector changed during this turn; delivery was not started.",
      "where": "Gateway log (not retried)",
      "cause": "The channel account restarted or was re-pinned during the agent's turn.",
      "fix": "Ask the agent again once the connector is READY.",
      "verify": "Reply appears."
    },
    {
      "id": "one-text-part-only",
      "component": "plugin-runtime",
      "text": "Octopus Prime outbound currently supports one durable text part only",
      "where": "Send error",
      "cause": "The agent tried to send media or a multi-part message.",
      "fix": "Agents reply with plain text only; no files or media.",
      "verify": "Text replies arrive."
    },
    {
      "id": "durable-identities-required",
      "component": "plugin-runtime",
      "text": "Durable outbound, parent event, and channel identities are required",
      "where": "Send error",
      "cause": "The agent tried to send something that is not a reply to an Octopus Prime message (for example a proactive send).",
      "fix": "Agents can only answer messages they received from Octopus Prime.",
      "verify": "—"
    },
    {
      "id": "durable-adapter-required",
      "component": "plugin-runtime",
      "text": "Octopus Prime outbound requires the durable message adapter",
      "where": "Send error",
      "cause": "A non-durable send path was used.",
      "fix": "Only replies to received messages are supported.",
      "verify": "—"
    },
    {
      "id": "core-managed-delivery-required",
      "component": "plugin-runtime",
      "text": "Octopus Prime replies require durable core-managed delivery",
      "where": "Send error",
      "cause": "A non-durable send path was used.",
      "fix": "Only replies to received messages are supported.",
      "verify": "—"
    },
    {
      "id": "pilot-default-account",
      "component": "plugin-runtime",
      "text": "Build 10 pilot outbound supports only the octopus-prime default account",
      "where": "Send error (permanent)",
      "cause": "A send targeted a non-default account.",
      "fix": "Use only the default account.",
      "verify": "—"
    },
    {
      "id": "pilot-channel-target",
      "component": "plugin-runtime",
      "text": "Build 10 pilot outbound requires a channel target",
      "where": "Send error (permanent)",
      "cause": "A send targeted something other than an Octopus Prime conversation.",
      "fix": "Only reply within the conversation the message came from.",
      "verify": "—"
    },
    {
      "id": "runtime-not-bound",
      "component": "plugin-runtime",
      "text": "Octopus Prime host runtime is not bound",
      "where": "Gateway startup log",
      "cause": "Startup race inside the Gateway.",
      "fix": "openclaw gateway restart; if it persists reinstall the plugin package with --force.",
      "verify": "Connector READY."
    },
    {
      "id": "runtime-unavailable",
      "component": "plugin-runtime",
      "text": "Octopus Prime host runtime is unavailable",
      "where": "Gateway startup log",
      "cause": "Startup race or failed plugin load.",
      "fix": "openclaw gateway restart; check openclaw plugins inspect octopus-prime --runtime --json.",
      "verify": "Connector READY."
    },
    {
      "id": "account-already-running",
      "component": "plugin-runtime",
      "text": "Octopus Prime connector account is already running",
      "where": "Gateway startup log",
      "cause": "Double start of the channel account.",
      "fix": "openclaw gateway restart.",
      "verify": "Connector READY."
    },
    {
      "id": "transport-already-started",
      "component": "plugin-runtime",
      "text": "Octopus Prime transport is already started",
      "where": "Gateway startup log",
      "cause": "Double start of the transport.",
      "fix": "openclaw gateway restart.",
      "verify": "Connector READY."
    },
    {
      "id": "old-build-thread-mismatch",
      "component": "plugin-runtime",
      "text": "prepared payload capability mismatch (thread)",
      "where": "Gateway log",
      "cause": "Plugin build older than 1.1.0.",
      "fix": "Install plugin 1.1.0 (openclaw plugins install <plugin package> --force).",
      "verify": "Replies arrive."
    },
    {
      "id": "old-build-sender",
      "component": "plugin-runtime",
      "text": "The reply channel changed or cannot preserve its sender",
      "where": "Gateway log",
      "cause": "Plugin build older than 1.1.0.",
      "fix": "Install plugin 1.1.0.",
      "verify": "Replies arrive."
    },
    {
      "id": "old-build-claim-lost",
      "component": "plugin-runtime",
      "text": "Delivery platform claim was lost",
      "where": "Gateway log",
      "cause": "Plugin build older than 1.1.0.",
      "fix": "Install plugin 1.1.0.",
      "verify": "Replies arrive."
    },
    {
      "id": "config-repair-not-inspected",
      "component": "plugin-runtime",
      "text": "Plugin config repair could not be inspected",
      "where": "Output of openclaw plugins install --force or openclaw plugins update on OpenClaw 2026.9.8 (reported in the plugin's own notes; not OpenClaw documentation wording)",
      "cause": "Replacing a plugin build that lacks a Doctor contract.",
      "fix": "Install plugin 1.1.0, which ships the Doctor contract.",
      "verify": "The install completes; openclaw plugins inspect octopus-prime --runtime --json shows loaded."
    },
    {
      "id": "close-4401",
      "component": "connection-close-code",
      "text": "4401",
      "where": "Close code in octopus-prime connector socket closed (code 4401)",
      "cause": "The connection carried no credential.",
      "fix": "Rerun setup with a new code (channels.octopus-prime.connectorToken is missing).",
      "verify": "Connector READY."
    },
    {
      "id": "close-4403",
      "component": "connection-close-code",
      "text": "4403",
      "where": "Close code in octopus-prime connector socket closed (code 4403)",
      "cause": "Credential unknown or revoked, organization archived, or replaced by a newer connection using the same credential (two Gateways or processes with the same config).",
      "fix": "Revoked/rotated: Connect OpenClaw (or New setup code) and rerun setup. Duplicate: stop the second Gateway/profile using the same config, or give it its own connector. Archived organization: an Owner restores it.",
      "verify": "No repeating 4403; connector READY."
    },
    {
      "id": "close-4426",
      "component": "connection-close-code",
      "text": "4426",
      "where": "Close code; connector chip INCOMPATIBLE",
      "cause": "Protocol token not accepted, or no protocol negotiation within 5 s.",
      "fix": "Install the plugin package Octopus Prime currently provides (plugin 1.1.0 sends 2026.9.7); check that nothing delays the connection start.",
      "verify": "Connector READY."
    },
    {
      "id": "close-1002",
      "component": "connection-close-code",
      "text": "1002",
      "where": "Close code",
      "cause": "Malformed frame, or the agent roster was rejected (more than 1000 agents, id longer than 128 characters, duplicate ids, name longer than 256, description longer than 4096).",
      "fix": "Fix agent ids, names or descriptions in OpenClaw; update the plugin if frames are malformed.",
      "verify": "Connector READY; agents listed."
    },
    {
      "id": "close-1001",
      "component": "connection-close-code",
      "text": "1001",
      "where": "Close code",
      "cause": "No frame for 75 s (idle connection).",
      "fix": "Check proxies or firewalls that cut idle or long-lived connections; heartbeats run every 25 s.",
      "verify": "No repeating 1001."
    },
    {
      "id": "close-1011",
      "component": "connection-close-code",
      "text": "1011",
      "where": "Close code",
      "cause": "Service-side error.",
      "fix": "Transient; the plugin reconnects. Contact support if it repeats.",
      "verify": "Connector READY."
    },
    {
      "id": "close-1012",
      "component": "connection-close-code",
      "text": "1012",
      "where": "Close code",
      "cause": "The Octopus Prime service restarted.",
      "fix": "Nothing; the plugin reconnects automatically.",
      "verify": "Connector READY."
    },
    {
      "id": "close-1006",
      "component": "connection-close-code",
      "text": "1006",
      "where": "Close code reported locally when the connection dropped without a close frame",
      "cause": "Network drop.",
      "fix": "Nothing if occasional; the plugin reconnects.",
      "verify": "Connector READY."
    },
    {
      "id": "ack_timeout",
      "component": "delivery-failure",
      "text": "ack_timeout",
      "where": "Chip FAILED",
      "cause": "The plugin did not acknowledge within 20 s on 5 offers (Gateway reachable but not processing, plugin errors).",
      "fix": "Check openclaw channels logs --channel octopus-prime and openclaw logs --follow; fix the plugin or Gateway; send the message again.",
      "verify": "A new message reaches RESPONDED."
    },
    {
      "id": "reply_timeout",
      "component": "delivery-failure",
      "text": "reply_timeout",
      "where": "Chip FAILED after WORKING or RECEIVED",
      "cause": "No progress for 10 minutes (no reply and no Working signal), or the Gateway was down past that limit.",
      "fix": "Check the agent's model/provider and tools in openclaw logs --follow. A late reply is still saved and shown.",
      "verify": "Next message reaches RESPONDED."
    },
    {
      "id": "route_unavailable",
      "component": "delivery-failure",
      "text": "route_unavailable",
      "where": "Chip FAILED",
      "cause": "The agent is inactive, no longer announced by its Gateway, no longer in the conversation, or the conversation is archived.",
      "fix": "Restore the agent in OpenClaw or in the conversation; use an active conversation.",
      "verify": "Next message reaches RESPONDED."
    },
    {
      "id": "route_identity_changed",
      "component": "delivery-failure",
      "text": "route_identity_changed",
      "where": "Chip FAILED",
      "cause": "The agent's OpenClaw id changed after the message was accepted.",
      "fix": "Keep OpenClaw agent ids stable; message the agent again.",
      "verify": "Next message reaches RESPONDED."
    },
    {
      "id": "stable_identity_missing",
      "component": "delivery-failure",
      "text": "stable_identity_missing",
      "where": "Chip FAILED",
      "cause": "The sender or the agent's OpenClaw id was missing.",
      "fix": "Send again; contact support if it repeats.",
      "verify": "—"
    },
    {
      "id": "sender_access_revoked",
      "component": "delivery-failure",
      "text": "sender_access_revoked",
      "where": "Chip FAILED",
      "cause": "The sender was deleted, deactivated or is no longer a participant.",
      "fix": "Nothing; the message is not delivered on purpose.",
      "verify": "—"
    },
    {
      "id": "source_sender_mismatch",
      "component": "delivery-failure",
      "text": "source_sender_mismatch",
      "where": "Chip FAILED",
      "cause": "The stored sender no longer matches the message.",
      "fix": "Contact support if it repeats.",
      "verify": "—"
    },
    {
      "id": "source_retention_expired",
      "component": "delivery-failure",
      "text": "source_retention_expired",
      "where": "Delivery state expired",
      "cause": "The message passed the 30-day window before the Gateway came back.",
      "fix": "Send a new message.",
      "verify": "—"
    },
    {
      "id": "message_removed",
      "component": "delivery-failure",
      "text": "message_removed",
      "where": "Delivery state cancelled",
      "cause": "The source message was removed.",
      "fix": "Nothing.",
      "verify": "—"
    },
    {
      "id": "sender_account_revoked",
      "component": "delivery-failure",
      "text": "sender_account_revoked",
      "where": "Delivery state cancelled",
      "cause": "The sender deleted their account; their queued agent deliveries are cancelled.",
      "fix": "Nothing.",
      "verify": "—"
    },
    {
      "id": "connector_rejected",
      "component": "delivery-failure",
      "text": "connector_rejected",
      "where": "last_error of a FAILED delivery",
      "cause": "The plugin rejected the delivery (for example Agent is not currently announced by this connector).",
      "fix": "See the plugin rejection reason in openclaw channels logs --channel octopus-prime.",
      "verify": "Next message reaches RESPONDED."
    },
    {
      "id": "invalid-or-used-setup-code",
      "component": "service-http",
      "text": "Invalid or used setup code",
      "where": "HTTP 404 {\"detail\": …} — bootstrap; setup-code exchange",
      "cause": "The code was mistyped, already used, or replaced by a newer code.",
      "fix": "Web app: New setup code; rerun setup within 15 minutes.",
      "verify": "Setup succeeds."
    },
    {
      "id": "setup-code-expired",
      "component": "service-http",
      "text": "Setup code expired",
      "where": "HTTP 410 {\"detail\": …} — bootstrap; setup-code exchange",
      "cause": "More than 15 minutes passed.",
      "fix": "New setup code; rerun setup.",
      "verify": "Setup succeeds."
    },
    {
      "id": "connector-not-found",
      "component": "service-http",
      "text": "Connector not found",
      "where": "HTTP 404 {\"detail\": …} — bootstrap; setup-code exchange",
      "cause": "The connector no longer exists.",
      "fix": "Connect OpenClaw again and use its code.",
      "verify": "Setup succeeds."
    },
    {
      "id": "connector-revoked",
      "component": "service-http",
      "text": "Connector revoked",
      "where": "HTTP 404 {\"detail\": …} — bootstrap; setup-code exchange",
      "cause": "The connector was revoked.",
      "fix": "Connect OpenClaw (new connector) and use its code.",
      "verify": "Setup succeeds."
    },
    {
      "id": "unsupported-plugin-api",
      "component": "service-http",
      "text": "Unsupported OpenClaw plugin API <v>. Supported: ['2026.9.7']",
      "where": "HTTP 426 {\"detail\": …} — bootstrap; setup-code exchange (checked before the code is used up)",
      "cause": "The plugin sends a protocol token the service does not accept (an unsupported plugin build). <v> is the plugin's token, not your OpenClaw version.",
      "fix": "Install the plugin package Octopus Prime currently provides (1.1.0 sends 2026.9.7); the same code still works if not expired.",
      "verify": "Setup succeeds."
    },
    {
      "id": "organization-archived",
      "component": "service-http",
      "text": "Organization is archived",
      "where": "HTTP 409 {\"detail\": …} — organization; any organization action, including setup",
      "cause": "The organization was archived.",
      "fix": "An Owner restores the organization.",
      "verify": "Actions work again."
    },
    {
      "id": "only-owner-archived",
      "component": "service-http",
      "text": "Only an owner can access an archived organization",
      "where": "HTTP 403 {\"detail\": …} — organization; opening an archived organization",
      "cause": "Archived organizations are visible to Owners only.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "org-name-required",
      "component": "service-http",
      "text": "Organization name is required",
      "where": "HTTP 422 {\"detail\": …} — organization; create or rename organization",
      "cause": "Empty name.",
      "fix": "Provide a name.",
      "verify": "—"
    },
    {
      "id": "only-owner-archive",
      "component": "service-http",
      "text": "Only an owner can archive an organization",
      "where": "HTTP 403 {\"detail\": …} — organization; archive organization",
      "cause": "Role too low.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "settle-billing-before-archive",
      "component": "service-http",
      "text": "Settle or cancel organization billing before archiving",
      "where": "HTTP 409 {\"detail\": …} — organization; archive organization",
      "cause": "An active subscription exists.",
      "fix": "Cancel or settle billing first.",
      "verify": "—"
    },
    {
      "id": "only-owner-restore",
      "component": "service-http",
      "text": "Only an owner can restore an organization",
      "where": "HTTP 403 {\"detail\": …} — organization; restore organization",
      "cause": "Role too low.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "only-owner-close",
      "component": "service-http",
      "text": "Only an owner can close an organization",
      "where": "HTTP 403 {\"detail\": …} — organization; close organization",
      "cause": "Role too low.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "not-authenticated",
      "component": "service-http",
      "text": "Not authenticated",
      "where": "HTTP 401 {\"detail\": …} — auth; any signed-in action",
      "cause": "Missing or expired session (sessions last 7 days).",
      "fix": "Sign in again.",
      "verify": "—"
    },
    {
      "id": "cross-origin-write",
      "component": "service-http",
      "text": "Cross-origin write refused",
      "where": "HTTP 403 {\"detail\": …} — auth; browser write from another site",
      "cause": "Requests must come from the official app.",
      "fix": "Use https://app.octopusprimeai.com or the mobile apps.",
      "verify": "—"
    },
    {
      "id": "terms-required",
      "component": "service-http",
      "text": "Accept the Terms of Use before posting or uploading",
      "where": "HTTP 428 {\"detail\": …} — auth; posting, uploading, scheduling",
      "cause": "Terms of Use not accepted.",
      "fix": "Accept the Terms in the app (I agree & continue).",
      "verify": "Posting works."
    },
    {
      "id": "insufficient-role",
      "component": "service-http",
      "text": "Insufficient role",
      "where": "HTTP 403 {\"detail\": …} — auth; admin actions",
      "cause": "Your role does not allow this.",
      "fix": "Ask an Owner or Admin.",
      "verify": "—"
    },
    {
      "id": "not-a-member",
      "component": "service-http",
      "text": "Not a member of this organization",
      "where": "HTTP 403 {\"detail\": …} — auth; any organization action",
      "cause": "You are not an active member.",
      "fix": "Accept the invitation or ask to be invited.",
      "verify": "—"
    },
    {
      "id": "account-unavailable-fenced",
      "component": "service-http",
      "text": "Account unavailable",
      "where": "HTTP 403 {\"detail\": …} — auth; any action after account changes",
      "cause": "The account is deleted or deactivated.",
      "fix": "Sign in again; contact an Owner if deactivated.",
      "verify": "—"
    },
    {
      "id": "account-changed",
      "component": "service-http",
      "text": "Account changed",
      "where": "HTTP 409 {\"detail\": …} — auth; any action",
      "cause": "Account state changed during the request.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "organization-not-found",
      "component": "service-http",
      "text": "Organization not found",
      "where": "HTTP 404 {\"detail\": …} — auth; any organization action",
      "cause": "Unknown or inaccessible organization.",
      "fix": "Switch to an organization you belong to.",
      "verify": "—"
    },
    {
      "id": "invalid-apple-token",
      "component": "service-http",
      "text": "Invalid Apple identity token",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Sign in with Apple",
      "cause": "The Apple sign-in could not be verified.",
      "fix": "Retry sign-in.",
      "verify": "—"
    },
    {
      "id": "invalid-google-token",
      "component": "service-http",
      "text": "Invalid Google identity token",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Sign in with Google",
      "cause": "The Google sign-in could not be verified.",
      "fix": "Retry sign-in.",
      "verify": "—"
    },
    {
      "id": "verified-apple-email",
      "component": "service-http",
      "text": "Verified Apple email required for new sign-in",
      "where": "HTTP 401 {\"detail\": …} — sign-in; first Apple sign-in",
      "cause": "New accounts need a verified e-mail from the provider.",
      "fix": "Use an Apple ID with a verified e-mail, or sign in with Google.",
      "verify": "—"
    },
    {
      "id": "verified-google-email",
      "component": "service-http",
      "text": "Verified Google email required for new sign-in",
      "where": "HTTP 401 {\"detail\": …} — sign-in; first Google sign-in",
      "cause": "New accounts need a verified e-mail.",
      "fix": "Use a verified Google account.",
      "verify": "—"
    },
    {
      "id": "apple-ownership-conflict",
      "component": "service-http",
      "text": "Apple account ownership conflict",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Apple sign-in",
      "cause": "The Apple identity is linked differently than expected.",
      "fix": "Sign in with the provider and e-mail used originally; contact support if it persists.",
      "verify": "—"
    },
    {
      "id": "google-ownership-conflict",
      "component": "service-http",
      "text": "Google account ownership conflict",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Google sign-in",
      "cause": "As above.",
      "fix": "As above.",
      "verify": "—"
    },
    {
      "id": "apple-ownership-changed",
      "component": "service-http",
      "text": "Apple account ownership changed; retry sign-in",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Apple sign-in",
      "cause": "Linking changed during sign-in.",
      "fix": "Retry sign-in.",
      "verify": "—"
    },
    {
      "id": "google-ownership-changed",
      "component": "service-http",
      "text": "Google account ownership changed; retry sign-in",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Google sign-in",
      "cause": "Linking changed during sign-in.",
      "fix": "Retry sign-in.",
      "verify": "—"
    },
    {
      "id": "ambiguous-apple",
      "component": "service-http",
      "text": "Ambiguous Apple account",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Apple sign-in",
      "cause": "The identity matches more than one account.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "ambiguous-google",
      "component": "service-http",
      "text": "Ambiguous Google account",
      "where": "HTTP 401 {\"detail\": …} — sign-in; Google sign-in",
      "cause": "As above.",
      "fix": "Contact support.",
      "verify": "—"
    },
    {
      "id": "message-empty",
      "component": "service-http",
      "text": "Message is empty",
      "where": "HTTP 400 {\"detail\": …} — messages; send message or schedule",
      "cause": "No text and no files.",
      "fix": "Write something.",
      "verify": "—"
    },
    {
      "id": "conversation-blocked",
      "component": "service-http",
      "text": "This conversation is blocked",
      "where": "HTTP 403 {\"detail\": …} — messages; send in a DM",
      "cause": "One of the two people blocked the other.",
      "fix": "The blocker can unblock in Blocked users.",
      "verify": "—"
    },
    {
      "id": "parent-not-found",
      "component": "service-http",
      "text": "Parent message not found",
      "where": "HTTP 404 {\"detail\": …} — messages; reply in thread",
      "cause": "The thread root is gone (for example past 30 days).",
      "fix": "Post a new message.",
      "verify": "—"
    },
    {
      "id": "channel-not-found",
      "component": "service-http",
      "text": "Channel not found",
      "where": "HTTP 404 {\"detail\": …} — messages; any conversation action",
      "cause": "Unknown conversation or no access.",
      "fix": "Check membership.",
      "verify": "—"
    },
    {
      "id": "client-id-conflict",
      "component": "service-http",
      "text": "Client message ID already identifies a different message",
      "where": "HTTP 409 {\"detail\": …} — messages; send message",
      "cause": "The same client_message_id was reused with different content.",
      "fix": "Use a new client_message_id for new content.",
      "verify": "—"
    },
    {
      "id": "cursor-requires-before",
      "component": "service-http",
      "text": "Message cursor requires before and before_id",
      "where": "HTTP 422 {\"detail\": …} — messages; history paging",
      "cause": "Incomplete paging cursor.",
      "fix": "Send both values.",
      "verify": "—"
    },
    {
      "id": "source-message-expired",
      "component": "service-http",
      "text": "Source message expired",
      "where": "HTTP 410 {\"detail\": …} — messages; retry of a delivery",
      "cause": "The message is past the 30-day window.",
      "fix": "Send a new message.",
      "verify": "—"
    },
    {
      "id": "delivery-not-found",
      "component": "service-http",
      "text": "Delivery not found",
      "where": "HTTP 404 {\"detail\": …} — messages; retry of a delivery",
      "cause": "Unknown delivery.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "pick-person-or-agent",
      "component": "service-http",
      "text": "Pick a person or an agent",
      "where": "HTTP 400 {\"detail\": …} — dms; start a DM",
      "cause": "Nothing selected.",
      "fix": "Choose a person or an agent.",
      "verify": "—"
    },
    {
      "id": "cannot-dm-yourself",
      "component": "service-http",
      "text": "Cannot DM yourself",
      "where": "HTTP 400 {\"detail\": …} — dms; start a DM",
      "cause": "You picked yourself.",
      "fix": "Pick someone else.",
      "verify": "—"
    },
    {
      "id": "user-not-active",
      "component": "service-http",
      "text": "User is not an active member",
      "where": "HTTP 400 {\"detail\": …} — dms; start a DM",
      "cause": "The person is not an active member.",
      "fix": "Invite or reactivate them.",
      "verify": "—"
    },
    {
      "id": "agent-not-available",
      "component": "service-http",
      "text": "Agent is not available",
      "where": "HTTP 400 {\"detail\": …} — dms; start an agent DM",
      "cause": "The agent is inactive, revoked or no longer announced by its Gateway.",
      "fix": "Make sure its Gateway is connected and the agent exists in OpenClaw.",
      "verify": "Agent DM opens."
    },
    {
      "id": "cannot-start-conversation",
      "component": "service-http",
      "text": "Cannot start a conversation with this user",
      "where": "HTTP 403 {\"detail\": …} — dms; start a DM",
      "cause": "A block exists between the two people.",
      "fix": "The blocker can unblock.",
      "verify": "—"
    },
    {
      "id": "plan-humans-limit",
      "component": "service-http",
      "text": "This organization's plan allows N active human(s)",
      "where": "HTTP 409 {\"detail\": …} — plan; invite, accept invitation, reactivate member",
      "cause": "The people limit of the plan (plus add-ons) is reached.",
      "fix": "Owner/Admin adds Extra human add-ons or upgrades.",
      "verify": "The action succeeds."
    },
    {
      "id": "plan-agents-limit",
      "component": "service-http",
      "text": "This organization's plan allows N AI agent(s)",
      "where": "HTTP 409 {\"detail\": …} — plan; new agent DM, add agent to channel",
      "cause": "The agent limit is reached.",
      "fix": "Owner/Admin adds Extra AI agent add-ons or upgrades (maximum 50).",
      "verify": "The action succeeds."
    },
    {
      "id": "agent-cap-50",
      "component": "service-http",
      "text": "An organization can have at most 50 AI agents. Contact us to raise this limit.",
      "where": "HTTP 409 {\"detail\": …} — plan; plan or add-on change",
      "cause": "More than 50 agents requested.",
      "fix": "Contact support@octopusprimeai.com.",
      "verify": "—"
    },
    {
      "id": "subscription-inactive",
      "component": "service-http",
      "text": "Your organization's subscription is inactive. An owner or admin must activate billing.",
      "where": "HTTP 402 {\"detail\": …} — plan; posting after the trial ended or payment lapsed",
      "cause": "No active subscription.",
      "fix": "An Owner/Admin chooses a plan in the web app.",
      "verify": "Posting works."
    },
    {
      "id": "unknown-plan",
      "component": "service-http",
      "text": "Unknown plan",
      "where": "HTTP 400 {\"detail\": …} — plan; checkout",
      "cause": "Invalid plan.",
      "fix": "Choose Starter, Pro or Business.",
      "verify": "—"
    },
    {
      "id": "checkout-being-opened",
      "component": "service-http",
      "text": "A checkout for this organization is being opened. Try again in a moment.",
      "where": "HTTP 409 {\"detail\": …} — plan; checkout",
      "cause": "Another checkout is in progress.",
      "fix": "Wait and retry.",
      "verify": "—"
    },
    {
      "id": "subscription-already-active",
      "component": "service-http",
      "text": "Subscription already active",
      "where": "HTTP 409 {\"detail\": …} — plan; checkout",
      "cause": "Already subscribed.",
      "fix": "Change the plan instead.",
      "verify": "—"
    },
    {
      "id": "no-billing-account",
      "component": "service-http",
      "text": "No billing account yet",
      "where": "HTTP 409 {\"detail\": …} — plan; payment settings",
      "cause": "No subscription created yet.",
      "fix": "Choose a plan first.",
      "verify": "—"
    },
    {
      "id": "no-active-subscription",
      "component": "service-http",
      "text": "No active subscription. Choose a plan at checkout.",
      "where": "HTTP 409 {\"detail\": …} — plan; plan change",
      "cause": "No subscription to change.",
      "fix": "Choose a plan.",
      "verify": "—"
    },
    {
      "id": "channel-agent-limit",
      "component": "service-http",
      "text": "Channel agent limit (5) reached",
      "where": "HTTP 409 {\"detail\": …} — channels; add agent to channel",
      "cause": "The channel already has 5 agents.",
      "fix": "Remove an agent or use another channel.",
      "verify": "—"
    },
    {
      "id": "manager-not-assigned",
      "component": "service-http",
      "text": "Manager is not assigned to this channel",
      "where": "HTTP 403 {\"detail\": …} — channels; channel management",
      "cause": "Managers manage only channels they are in.",
      "fix": "Ask an Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "invalid-channel-type",
      "component": "service-http",
      "text": "Invalid channel type",
      "where": "HTTP 400 {\"detail\": …} — channels; create channel",
      "cause": "Unsupported type.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "dm-not-channel",
      "component": "service-http",
      "text": "Direct messages cannot be administered as channels",
      "where": "HTTP 409 {\"detail\": …} — channels; channel management on a DM",
      "cause": "DMs have no channel settings.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "restore-before-edit",
      "component": "service-http",
      "text": "Restore the channel before editing it",
      "where": "HTTP 409 {\"detail\": …} — channels; edit archived channel",
      "cause": "The channel is archived.",
      "fix": "Restore it first.",
      "verify": "—"
    },
    {
      "id": "channel-name-required",
      "component": "service-http",
      "text": "Channel name is required",
      "where": "HTTP 422 {\"detail\": …} — channels; create or rename channel",
      "cause": "Empty name.",
      "fix": "Provide a name.",
      "verify": "—"
    },
    {
      "id": "org-wide-not-private",
      "component": "service-http",
      "text": "Organization-wide channels cannot be private",
      "where": "HTTP 409 {\"detail\": …} — channels; channel settings",
      "cause": "#announcements is organization-wide.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "org-wide-not-archivable",
      "component": "service-http",
      "text": "Organization-wide channels cannot be archived",
      "where": "HTTP 409 {\"detail\": …} — channels; archive channel",
      "cause": "#announcements cannot be archived.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "no-channel-changes",
      "component": "service-http",
      "text": "No channel changes supplied",
      "where": "HTTP 422 {\"detail\": …} — channels; channel update",
      "cause": "Nothing changed.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "user-not-active-in-org",
      "component": "service-http",
      "text": "User is not an active member of this organization",
      "where": "HTTP 400 {\"detail\": …} — channels; add member to channel",
      "cause": "The person is not an active member.",
      "fix": "Invite or reactivate them first.",
      "verify": "—"
    },
    {
      "id": "assign-elevated-role",
      "component": "service-http",
      "text": "Only an owner or admin can assign an Owner, Admin, or Manager to a channel",
      "where": "HTTP 403 {\"detail\": …} — channels; channel membership",
      "cause": "Managers cannot add elevated roles.",
      "fix": "Ask an Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "unassign-elevated-role",
      "component": "service-http",
      "text": "Only an owner or admin can unassign an Owner, Admin, or Manager from a channel",
      "where": "HTTP 403 {\"detail\": …} — channels; channel membership",
      "cause": "Managers cannot remove elevated roles.",
      "fix": "Ask an Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "channel-changed",
      "component": "service-http",
      "text": "Channel changed",
      "where": "HTTP 409 {\"detail\": …} — channels; channel update",
      "cause": "Concurrent change.",
      "fix": "Reload and retry.",
      "verify": "—"
    },
    {
      "id": "agent-not-found",
      "component": "service-http",
      "text": "Agent not found",
      "where": "HTTP 404 {\"detail\": …} — channels; agent actions",
      "cause": "Unknown agent.",
      "fix": "Check the agent list in OpenClaw Agents.",
      "verify": "—"
    },
    {
      "id": "already-member",
      "component": "service-http",
      "text": "User is already a member",
      "where": "HTTP 409 {\"detail\": …} — invitations; invite",
      "cause": "Already in the organization.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "invite-pending",
      "component": "service-http",
      "text": "An invitation is already pending for this email",
      "where": "HTTP 409 {\"detail\": …} — invitations; invite",
      "cause": "An open invitation exists.",
      "fix": "Wait for acceptance or withdraw it first.",
      "verify": "—"
    },
    {
      "id": "invite-not-found",
      "component": "service-http",
      "text": "Invitation not found or already used",
      "where": "HTTP 404 {\"detail\": …} — invitations; accept invitation",
      "cause": "Withdrawn, used or unknown.",
      "fix": "Ask for a new invitation.",
      "verify": "—"
    },
    {
      "id": "invite-different-email",
      "component": "service-http",
      "text": "This invitation was sent to a different email",
      "where": "HTTP 403 {\"detail\": …} — invitations; accept invitation",
      "cause": "Signed in with another address (common with Apple Hide My Email).",
      "fix": "Sign in with the invited address, or ask to invite the address you use.",
      "verify": "—"
    },
    {
      "id": "invite-expired",
      "component": "service-http",
      "text": "Invitation expired",
      "where": "HTTP 410 {\"detail\": …} — invitations; accept invitation",
      "cause": "Older than 14 days.",
      "fix": "Ask for a new invitation.",
      "verify": "—"
    },
    {
      "id": "owner-invite-lacks-authority",
      "component": "service-http",
      "text": "Ownership invitation lacks verified authority; request a new owner-issued invitation",
      "where": "HTTP 403 {\"detail\": …} — invitations; accept Owner invitation",
      "cause": "The Owner invitation is not valid.",
      "fix": "Ask a current Owner to invite you again.",
      "verify": "—"
    },
    {
      "id": "owner-invite-withdrawn",
      "component": "service-http",
      "text": "This owner invitation was withdrawn because the person who sent it is no longer an owner of this organization. Ask a current owner to invite you again.",
      "where": "HTTP 409 {\"detail\": …} — invitations; accept Owner invitation",
      "cause": "The inviter is no longer an Owner.",
      "fix": "Ask a current Owner.",
      "verify": "—"
    },
    {
      "id": "invalid-role",
      "component": "service-http",
      "text": "Invalid role",
      "where": "HTTP 400 {\"detail\": …} — roles; role change",
      "cause": "Unknown role.",
      "fix": "Use owner, admin, manager or member.",
      "verify": "—"
    },
    {
      "id": "sole-owner-remove",
      "component": "service-http",
      "text": "Cannot remove the sole active owner",
      "where": "HTTP 409 {\"detail\": …} — roles; role change or removal",
      "cause": "The organization must keep one Owner.",
      "fix": "Make someone else Owner first.",
      "verify": "—"
    },
    {
      "id": "sole-owner-deactivate",
      "component": "service-http",
      "text": "Cannot deactivate the sole owner",
      "where": "HTTP 409 {\"detail\": …} — roles; deactivate member",
      "cause": "As above.",
      "fix": "Make someone else Owner first.",
      "verify": "—"
    },
    {
      "id": "owner-assign",
      "component": "service-http",
      "text": "Only an owner can assign ownership",
      "where": "HTTP 403 {\"detail\": …} — roles; role change",
      "cause": "Admins cannot grant Owner.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "owner-change",
      "component": "service-http",
      "text": "Only an owner can change ownership",
      "where": "HTTP 403 {\"detail\": …} — roles; role change",
      "cause": "Admins cannot change an Owner.",
      "fix": "Ask an Owner.",
      "verify": "—"
    },
    {
      "id": "invalid-status",
      "component": "service-http",
      "text": "Invalid status",
      "where": "HTTP 400 {\"detail\": …} — roles; member status change",
      "cause": "Unknown status.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "deleted-not-reactivatable",
      "component": "service-http",
      "text": "Deleted accounts cannot be reactivated",
      "where": "HTTP 409 {\"detail\": …} — roles; reactivate member",
      "cause": "The person deleted their account.",
      "fix": "Invite their new account.",
      "verify": "—"
    },
    {
      "id": "member-not-found",
      "component": "service-http",
      "text": "Member not found",
      "where": "HTTP 404 {\"detail\": …} — roles; member actions",
      "cause": "Unknown member.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "only-owner-delete",
      "component": "service-http",
      "text": "You are the only owner of '<org>'. Make another member an owner before deleting your account.",
      "where": "HTTP 409 {\"detail\": …} — account-deletion; delete account",
      "cause": "Sole Owner of an organization with other active members.",
      "fix": "Make another member an Owner, then delete.",
      "verify": "Deletion succeeds."
    },
    {
      "id": "settle-billing-delete",
      "component": "service-http",
      "text": "Settle or cancel billing for '<org>' before deleting your account.",
      "where": "HTTP 409 {\"detail\": …} — account-deletion; delete account",
      "cause": "Active billing on an organization you would close.",
      "fix": "Cancel or settle billing first.",
      "verify": "Deletion succeeds."
    },
    {
      "id": "checkout-open-delete",
      "component": "service-http",
      "text": "A checkout is open for '{name}'. Try again after it expires in {N minute(s)}.",
      "where": "HTTP 409 {\"detail\": …} — account-deletion; delete account",
      "cause": "A checkout session is open.",
      "fix": "Wait the stated time.",
      "verify": "Deletion succeeds."
    },
    {
      "id": "membership-changed",
      "component": "service-http",
      "text": "Membership changed; retry account deletion",
      "where": "HTTP 409 {\"detail\": …} — account-deletion; delete account",
      "cause": "Membership changed during deletion.",
      "fix": "Retry.",
      "verify": "Deletion succeeds."
    },
    {
      "id": "schedule-where",
      "component": "service-http",
      "text": "Messages can be scheduled only in a channel or an agent direct message",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "Person-to-person DM.",
      "fix": "Use a channel or agent DM.",
      "verify": "—"
    },
    {
      "id": "template-or-message",
      "component": "service-http",
      "text": "Choose a template or write a message",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "Neither text nor template.",
      "fix": "Provide one.",
      "verify": "—"
    },
    {
      "id": "schedule-too-long",
      "component": "service-http",
      "text": "A scheduled message can be at most 4000 characters",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "Text over 4,000 characters.",
      "fix": "Shorten it.",
      "verify": "—"
    },
    {
      "id": "invalid-start-time",
      "component": "service-http",
      "text": "Invalid start time",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "Unparseable time.",
      "fix": "Pick a valid time.",
      "verify": "—"
    },
    {
      "id": "time-in-future",
      "component": "service-http",
      "text": "Choose a time in the future",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "Start time not at least 30 s ahead.",
      "fix": "Pick a time further ahead.",
      "verify": "—"
    },
    {
      "id": "choose-when",
      "component": "service-http",
      "text": "Choose when to send the message",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "No time given for a one-time schedule.",
      "fix": "Pick a time.",
      "verify": "—"
    },
    {
      "id": "start-too-far",
      "component": "service-http",
      "text": "Start time is too far out (max 90 days)",
      "where": "HTTP 400 {\"detail\": …} — schedules; create schedule",
      "cause": "More than 90 days ahead.",
      "fix": "Pick an earlier time.",
      "verify": "—"
    },
    {
      "id": "schedule-limit",
      "component": "service-http",
      "text": "This organization already has 20 scheduled messages. Delete one before adding another.",
      "where": "HTTP 409 {\"detail\": …} — schedules; create schedule",
      "cause": "20 active or paused schedules exist.",
      "fix": "Delete one.",
      "verify": "—"
    },
    {
      "id": "client-schedule-conflict",
      "component": "service-http",
      "text": "Client schedule ID already identifies a different schedule",
      "where": "HTTP 409 {\"detail\": …} — schedules; create schedule",
      "cause": "Reused id with different content.",
      "fix": "Retry as a new schedule.",
      "verify": "—"
    },
    {
      "id": "only-active-pause",
      "component": "service-http",
      "text": "Only an active schedule can be paused",
      "where": "HTTP 409 {\"detail\": …} — schedules; pause",
      "cause": "Not active.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "only-creator-resume",
      "component": "service-http",
      "text": "Only the person who created this schedule can resume it",
      "where": "HTTP 403 {\"detail\": …} — schedules; resume",
      "cause": "Not the creator.",
      "fix": "Ask the creator, or create a new schedule.",
      "verify": "—"
    },
    {
      "id": "only-paused-resume",
      "component": "service-http",
      "text": "Only a paused schedule can be resumed",
      "where": "HTTP 409 {\"detail\": …} — schedules; resume",
      "cause": "Not paused.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "one-time-passed",
      "component": "service-http",
      "text": "This one-time schedule's time has passed",
      "where": "HTTP 409 {\"detail\": …} — schedules; resume",
      "cause": "The one-time slot is in the past.",
      "fix": "Create a new schedule.",
      "verify": "—"
    },
    {
      "id": "status-paused-active",
      "component": "service-http",
      "text": "Status must be paused or active",
      "where": "HTTP 422 {\"detail\": …} — schedules; update schedule",
      "cause": "Invalid status value.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "template-not-found",
      "component": "service-http",
      "text": "Template not found",
      "where": "HTTP 404 {\"detail\": …} — schedules; schedule from template",
      "cause": "Template deleted.",
      "fix": "Pick another template.",
      "verify": "—"
    },
    {
      "id": "schedule-not-found",
      "component": "service-http",
      "text": "Schedule not found",
      "where": "HTTP 404 {\"detail\": …} — schedules; schedule actions",
      "cause": "Deleted or unknown.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "report-own-message",
      "component": "service-http",
      "text": "You can't report your own message",
      "where": "HTTP 400 {\"detail\": …} — report-block; report",
      "cause": "—",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "already-removed",
      "component": "service-http",
      "text": "A moderator already removed this message",
      "where": "HTTP 409 {\"detail\": …} — report-block; report",
      "cause": "Already handled.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "report-yourself",
      "component": "service-http",
      "text": "You can't report yourself",
      "where": "HTTP 400 {\"detail\": …} — report-block; report person",
      "cause": "—",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "person-not-in-conversation",
      "component": "service-http",
      "text": "Person not found in this conversation",
      "where": "HTTP 404 {\"detail\": …} — report-block; report person",
      "cause": "The person is not in that conversation.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "message-not-found",
      "component": "service-http",
      "text": "Message not found",
      "where": "HTTP 404 {\"detail\": …} — report-block; report message",
      "cause": "Message gone (for example past 30 days).",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "block-yourself",
      "component": "service-http",
      "text": "Cannot block yourself",
      "where": "HTTP 400 {\"detail\": …} — report-block; block",
      "cause": "—",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "person-not-found",
      "component": "service-http",
      "text": "Person not found",
      "where": "HTTP 404 {\"detail\": …} — report-block; block",
      "cause": "Unknown person.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "agents-cannot-be-blocked",
      "component": "service-http",
      "text": "Agents can't be blocked. Report the message instead, or ask an owner or admin to remove the agent.",
      "where": "HTTP 400 {\"detail\": …} — report-block; block an agent",
      "cause": "Agents are not blockable.",
      "fix": "Report the message or ask an Owner/Admin to remove the agent from the channel.",
      "verify": "—"
    },
    {
      "id": "one-file-per-request",
      "component": "service-http",
      "text": "Upload one file per request",
      "where": "HTTP 400 {\"detail\": …} — files; upload",
      "cause": "More than one file in one upload.",
      "fix": "Upload files one by one.",
      "verify": "—"
    },
    {
      "id": "file-too-large",
      "component": "service-http",
      "text": "File \"<name>\" is larger than 5 MB",
      "where": "HTTP 413 {\"detail\": …} — files; upload",
      "cause": "Over 5 MB.",
      "fix": "Shrink or split the file.",
      "verify": "—"
    },
    {
      "id": "too-many-files",
      "component": "service-http",
      "text": "A message can include at most 5 files; this one has N",
      "where": "HTTP 400 {\"detail\": …} — files; send message",
      "cause": "More than 5 attachments.",
      "fix": "Send in several messages.",
      "verify": "—"
    },
    {
      "id": "duplicate-attachments",
      "component": "service-http",
      "text": "Duplicate attachments are not allowed",
      "where": "HTTP 400 {\"detail\": …} — files; send message",
      "cause": "Same file attached twice.",
      "fix": "Remove the duplicate.",
      "verify": "—"
    },
    {
      "id": "attachments-unavailable",
      "component": "service-http",
      "text": "One or more attachments are unavailable in this channel",
      "where": "HTTP 400 {\"detail\": …} — files; send message",
      "cause": "Attachment uploaded elsewhere or expired.",
      "fix": "Upload again in this conversation.",
      "verify": "—"
    },
    {
      "id": "type-not-allowed",
      "component": "service-http",
      "text": "This file type is not allowed",
      "where": "HTTP 400 {\"detail\": …} — files; upload",
      "cause": "Blocked type (executables, scripts, HTML, SVG, XML).",
      "fix": "Use an allowed format or share as text.",
      "verify": "—"
    },
    {
      "id": "unsupported-type",
      "component": "service-http",
      "text": "Unsupported file type",
      "where": "HTTP 400 {\"detail\": …} — files; upload",
      "cause": "Unrecognized type.",
      "fix": "Use an allowed format.",
      "verify": "—"
    },
    {
      "id": "file-expired",
      "component": "service-http",
      "text": "This file has expired",
      "where": "HTTP 410 {\"detail\": …} — files; download",
      "cause": "Older than 7 days.",
      "fix": "Ask the sender to share it again.",
      "verify": "—"
    },
    {
      "id": "file-not-found",
      "component": "service-http",
      "text": "File not found",
      "where": "HTTP 404 {\"detail\": …} — files; download",
      "cause": "Unknown file.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "file-forbidden",
      "component": "service-http",
      "text": "Forbidden",
      "where": "HTTP 403 {\"detail\": …} — files; download",
      "cause": "No access to that conversation.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "search-query-required",
      "component": "service-http",
      "text": "Search query is required",
      "where": "HTTP 422 {\"detail\": …} — search; search",
      "cause": "Empty query.",
      "fix": "Type a query.",
      "verify": "—"
    },
    {
      "id": "push-mode",
      "component": "service-http",
      "text": "mode must be one of all|mentions|mute",
      "where": "HTTP 422 {\"detail\": …} — notifications; notification settings",
      "cause": "Invalid mode.",
      "fix": "Use all, mentions or mute.",
      "verify": "—"
    },
    {
      "id": "push-time",
      "component": "service-http",
      "text": "time must be HH:MM (24-hour)",
      "where": "HTTP 422 {\"detail\": …} — notifications; quiet hours",
      "cause": "Invalid time format.",
      "fix": "Use HH:MM.",
      "verify": "—"
    },
    {
      "id": "push-timezone-required",
      "component": "service-http",
      "text": "timezone is required",
      "where": "HTTP 422 {\"detail\": …} — notifications; quiet hours",
      "cause": "Missing time zone.",
      "fix": "Provide an IANA time zone.",
      "verify": "—"
    },
    {
      "id": "push-invalid-timezone",
      "component": "service-http",
      "text": "invalid IANA timezone",
      "where": "HTTP 422 {\"detail\": …} — notifications; quiet hours",
      "cause": "Unknown time zone.",
      "fix": "Use a name like America/Phoenix.",
      "verify": "—"
    },
    {
      "id": "recording-too-short",
      "component": "service-http",
      "text": "Recording too short — try again",
      "where": "HTTP 400 {\"detail\": …} — voice; dictation",
      "cause": "Clip under 2 KB.",
      "fix": "Record longer.",
      "verify": "—"
    },
    {
      "id": "audio-too-large",
      "component": "service-http",
      "text": "Audio exceeds the 25 MB limit",
      "where": "HTTP 413 {\"detail\": …} — voice; dictation",
      "cause": "Clip over 25 MB.",
      "fix": "Record a shorter clip.",
      "verify": "—"
    },
    {
      "id": "could-not-transcribe",
      "component": "service-http",
      "text": "Could not transcribe audio",
      "where": "HTTP 502 {\"detail\": …} — voice; dictation",
      "cause": "Transcription failed.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "nothing-to-read",
      "component": "service-http",
      "text": "Nothing to read aloud",
      "where": "HTTP 400 {\"detail\": …} — voice; read aloud",
      "cause": "Message has no text.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "could-not-generate-audio",
      "component": "service-http",
      "text": "Could not generate audio",
      "where": "HTTP 502 {\"detail\": …} — voice; read aloud",
      "cause": "Speech generation failed.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "incident-not-found",
      "component": "service-http",
      "text": "Health Watch incident not found",
      "where": "HTTP 404 {\"detail\": …} — health-watch; acknowledge incident",
      "cause": "Unknown or expired incident (finished incidents are kept 7 days).",
      "fix": "Refresh Health Watch.",
      "verify": "—"
    },
    {
      "id": "incident-terminal",
      "component": "service-http",
      "text": "Health Watch incident is already terminal",
      "where": "HTTP 409 {\"detail\": …} — health-watch; acknowledge incident",
      "cause": "The incident already closed.",
      "fix": "Nothing to do.",
      "verify": "—"
    },
    {
      "id": "service-unavailable",
      "component": "service-http",
      "text": "Service unavailable",
      "where": "HTTP 503 {\"detail\": …} — service; GET /api/health/ready",
      "cause": "The service is not ready (starting or a dependency is down).",
      "fix": "Wait and retry.",
      "verify": "GET /api/health/ready returns {\"status\":\"ready\"}."
    },
    {
      "id": "database-unavailable",
      "component": "service-http",
      "text": "Database unavailable",
      "where": "HTTP 503 {\"detail\": …} — service; any request",
      "cause": "Temporary storage outage.",
      "fix": "Retry after a short wait.",
      "verify": "—"
    },
    {
      "id": "live-updates-off-web",
      "component": "app-ui",
      "text": "Live updates off — checking for new messages every few seconds",
      "where": "Web banner",
      "cause": "The app is refreshing open conversations every few seconds instead of receiving live pushes.",
      "fix": "Nothing; new messages still appear within seconds.",
      "verify": "—"
    },
    {
      "id": "live-updates-off-iphone",
      "component": "app-ui",
      "text": "Live updates off · open chats refresh every few seconds",
      "where": "iPhone banner",
      "cause": "As above.",
      "fix": "Nothing.",
      "verify": "—"
    },
    {
      "id": "reconnecting-banner",
      "component": "app-ui",
      "text": "Reconnecting…",
      "where": "Web banner",
      "cause": "A refresh of the conversation failed.",
      "fix": "Wait; it clears on the next successful refresh. Check your internet connection if it stays.",
      "verify": "—"
    },
    {
      "id": "could-not-load-connectors",
      "component": "app-ui",
      "text": "Could not load connectors",
      "where": "OpenClaw Agents dialog (with Retry)",
      "cause": "The connector list could not be loaded.",
      "fix": "Retry; sign in again if your session expired.",
      "verify": "—"
    },
    {
      "id": "could-not-create-connector",
      "component": "app-ui",
      "text": "Could not create connector",
      "where": "OpenClaw Agents dialog",
      "cause": "Connect OpenClaw failed (or the service detail is shown instead).",
      "fix": "Retry; check you are Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "could-not-create-setup-code",
      "component": "app-ui",
      "text": "Could not create a new setup code",
      "where": "OpenClaw Agents dialog",
      "cause": "New setup code failed.",
      "fix": "Retry; check you are Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "could-not-revoke",
      "component": "app-ui",
      "text": "Could not revoke connector",
      "where": "OpenClaw Agents dialog",
      "cause": "Revoke failed.",
      "fix": "Retry; check you are Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "connector-revoked-toast",
      "component": "app-ui",
      "text": "Connector revoked",
      "where": "OpenClaw Agents dialog (success)",
      "cause": "The connector was revoked.",
      "fix": "Disable or uninstall the plugin on that Gateway to stop its reconnect attempts.",
      "verify": "—"
    },
    {
      "id": "copy-failed",
      "component": "app-ui",
      "text": "Could not copy. Select the text and copy it manually.",
      "where": "OpenClaw Agents dialog",
      "cause": "Clipboard access failed.",
      "fix": "Use View or manually copy the prompt.",
      "verify": "—"
    },
    {
      "id": "no-https-backend",
      "component": "app-ui",
      "text": "A valid HTTPS backend address is required to prepare connection instructions.",
      "where": "OpenClaw Agents dialog",
      "cause": "The app could not build the setup prompt.",
      "fix": "Reload the web app; contact support if it persists.",
      "verify": "—"
    },
    {
      "id": "could-not-load-agents",
      "component": "app-ui",
      "text": "Could not load agents.",
      "where": "iPhone agents list (with Retry)",
      "cause": "The agent list could not be loaded.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "no-agents-connected",
      "component": "app-ui",
      "text": "No agents connected",
      "where": "iPhone agents list",
      "cause": "No connected Gateway has announced agents.",
      "fix": "Connect a Gateway (web app) and check it is READY.",
      "verify": "—"
    },
    {
      "id": "file-over-limit",
      "component": "app-ui",
      "text": "\"{name}\" is {size} — over the 5 MB limit, so it was not attached.",
      "where": "Composer",
      "cause": "File over 5 MB.",
      "fix": "Use a smaller file.",
      "verify": "—"
    },
    {
      "id": "file-too-large-upload",
      "component": "app-ui",
      "text": "\"{name}\" is too large to upload (the limit is 5 MB), so it was not attached.",
      "where": "Composer",
      "cause": "Upload refused as too large.",
      "fix": "Use a smaller file.",
      "verify": "—"
    },
    {
      "id": "file-expired-ui",
      "component": "app-ui",
      "text": "This file has expired.",
      "where": "Message attachment",
      "cause": "File older than 7 days.",
      "fix": "Ask the sender to share it again.",
      "verify": "—"
    },
    {
      "id": "cannot-post-here",
      "component": "app-ui",
      "text": "You cannot post here",
      "where": "Composer",
      "cause": "No permission to post in this conversation.",
      "fix": "Ask a channel manager or Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "accept-terms",
      "component": "app-ui",
      "text": "Accept the Terms of Use before posting",
      "where": "Composer",
      "cause": "Terms not accepted.",
      "fix": "Accept the Terms (I agree & continue).",
      "verify": "—"
    },
    {
      "id": "could-not-send",
      "component": "app-ui",
      "text": "Could not send message",
      "where": "Composer",
      "cause": "Sending failed.",
      "fix": "Retry; check connection and subscription status.",
      "verify": "—"
    },
    {
      "id": "trial-ended",
      "component": "app-ui",
      "text": "Your free trial has ended",
      "where": "Billing / paywall",
      "cause": "The 7-day trial ended without a plan.",
      "fix": "An Owner/Admin chooses a plan in the web app.",
      "verify": "Posting works."
    },
    {
      "id": "subscription-inactive-ui",
      "component": "app-ui",
      "text": "Subscription inactive",
      "where": "Billing / paywall",
      "cause": "No active subscription.",
      "fix": "An Owner/Admin chooses or fixes the plan.",
      "verify": "Posting works."
    },
    {
      "id": "access-paused",
      "component": "app-ui",
      "text": "Access is paused for this organization. Please ask an owner or admin to choose a plan.",
      "where": "Paywall (members)",
      "cause": "Trial ended or subscription inactive.",
      "fix": "Ask an Owner/Admin.",
      "verify": "Posting works."
    },
    {
      "id": "payment-failed",
      "component": "app-ui",
      "text": "Payment failed — please update your card",
      "where": "Billing",
      "cause": "A payment failed; the 7-day grace period runs.",
      "fix": "Owner/Admin updates the payment method in the web app.",
      "verify": "Notice disappears."
    },
    {
      "id": "iphone-paused-trial",
      "component": "app-ui",
      "text": "Access paused — trial ended. Open Settings.",
      "where": "iPhone banner",
      "cause": "Trial ended.",
      "fix": "Owner/Admin chooses a plan on the web.",
      "verify": "Posting works."
    },
    {
      "id": "iphone-paused-inactive",
      "component": "app-ui",
      "text": "Access paused — subscription inactive. Open Settings.",
      "where": "iPhone banner",
      "cause": "Subscription inactive.",
      "fix": "Owner/Admin fixes billing on the web.",
      "verify": "Posting works."
    },
    {
      "id": "invite-invalid-email",
      "component": "app-ui",
      "text": "Enter a valid email address (name@company.com).",
      "where": "Invite people",
      "cause": "Malformed address.",
      "fix": "Correct the address.",
      "verify": "—"
    },
    {
      "id": "invite-domain",
      "component": "app-ui",
      "text": "That email domain can’t receive invitations. Use a real work email.",
      "where": "Invite people",
      "cause": "The domain is not accepted for invitations.",
      "fix": "Use another address.",
      "verify": "—"
    },
    {
      "id": "account-deleted-signin",
      "component": "app-ui",
      "text": "Your account was deleted",
      "where": "Sign-in screen",
      "cause": "You deleted your account; all sessions ended.",
      "fix": "Signing in again starts a new, empty account.",
      "verify": "—"
    },
    {
      "id": "signed-out-everywhere",
      "component": "app-ui",
      "text": "You have been signed out on every device. Signing in again starts a new account.",
      "where": "Sign-in screen after deletion",
      "cause": "Account deletion.",
      "fix": "—",
      "verify": "—"
    },
    {
      "id": "hw-owner-admin-only",
      "component": "app-ui",
      "text": "Health Watch is available only to an Owner or Admin of an active organization.",
      "where": "iPhone Health Watch",
      "cause": "Role too low or organization inactive.",
      "fix": "Ask an Owner/Admin.",
      "verify": "—"
    },
    {
      "id": "hw-no-gateways",
      "component": "app-ui",
      "text": "No gateways are connected.",
      "where": "Health Watch",
      "cause": "No connector exists.",
      "fix": "Connect a Gateway.",
      "verify": "—"
    },
    {
      "id": "mic-denied",
      "component": "app-ui",
      "text": "Microphone access was denied",
      "where": "Dictation",
      "cause": "Microphone permission missing.",
      "fix": "Allow microphone access for the app or browser.",
      "verify": "—"
    },
    {
      "id": "recording-failed",
      "component": "app-ui",
      "text": "Recording failed — try again",
      "where": "Dictation",
      "cause": "Recording error.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "didnt-catch",
      "component": "app-ui",
      "text": "Didn't catch that — try again",
      "where": "Dictation",
      "cause": "No speech recognized.",
      "fix": "Speak again.",
      "verify": "—"
    },
    {
      "id": "transcription-failed",
      "component": "app-ui",
      "text": "Transcription failed",
      "where": "Dictation",
      "cause": "Transcription error.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "playback-failed",
      "component": "app-ui",
      "text": "Playback failed",
      "where": "Read aloud",
      "cause": "Audio playback error.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "could-not-read-aloud",
      "component": "app-ui",
      "text": "Could not read aloud",
      "where": "Read aloud",
      "cause": "Speech generation error.",
      "fix": "Retry.",
      "verify": "—"
    },
    {
      "id": "blocked-hidden",
      "component": "app-ui",
      "text": "Message from a blocked user hidden.",
      "where": "Conversation",
      "cause": "You blocked the sender.",
      "fix": "Unblock in Blocked users if wanted.",
      "verify": "—"
    }
  ]
}
