Skip to main content

troubleshoot

Use when a Chatwoot API call, CLI command or webhook fails or misbehaves - 401 or 403 with a valid token, 404 or an HTML page instead of JSON, 422 request errors, 429 rate limits, a webhook signature that never matches, or a CLI that works locally but not in CI. It maps the symptom to the cause and the fix. For building bots and webhooks use webhooks-automation, for CLI usage cli-recipes.

Source facts

Repository
Agents-Store/codex-plugins
Last source activity
November 1, 2026 at 02:46
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
troubleshoot
description
Use when a Chatwoot API call, CLI command or webhook fails or misbehaves - 401 or 403 with a valid token, 404 or an HTML page instead of JSON, 422 request errors, 429 rate limits, a webhook signature that never matches, or a CLI that works locally but not in CI. It maps the symptom to the cause and the fix. For building bots and webhooks use webhooks-automation, for CLI usage cli-recipes.
# Chatwoot Troubleshooting Diagnose and fix the common failure modes for the Chatwoot API, CLI, and webhooks. ## Quick diagnostics ```bash # 1. Is the base URL reachable? curl -sI "${CHATWOOT_BASE_URL}" | head -1 # 2. Is the token valid and which identity is it? curl -s -H "api-access-token: ${CHATWOOT_API_KEY}" \ "${CHATWOOT_BASE_URL}/api/v1/profile" | jq '{id, name, role}' # 3. Does the account scope resolve? curl -s -o /dev/null -w "%{http_code}\n" -H "api-access-token: ${CHATWOOT_API_KEY}" \ "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations" ``` ## Authentication & authorization | Symptom | Cause | Fix | |---------|-------|-----| | `401 Unauthorized` | Missing/typo'd `api-access-token` header | Send `-H "api-access-token: ${CHATWOOT_API_KEY}"` | | `401` with a valid token, only behind a reverse proxy | Proxy drops request headers with underscores (nginx default `underscores_in_headers off`; Caddy 2.6.4+) so `api_access_token` never arrives | Send the hyphenated `api-access-token` (same header for Chatwoot). The CLI needs v0.7.0+. See "Header check behind a proxy" below | | `401` with `Authorization: Bearer <token>` | Bearer is accepted only by Chatwoot v4.19.0+ (v4.18.0 is the latest release as of 2026-10-03) | Use `api-access-token` until the instance runs v4.19.0 or later | | `401` with a valid token | Right token, **wrong API family** | User token works on `/api/v1/...`, not `/platform/...`. Use the platform app token for Platform endpoints | | `403 Forbidden` | Token role too low | The action needs admin/agent permission the token lacks — use a token with the right role | | Platform calls all `401` | Platform API not enabled / wrong token | Platform token comes from the installation Super Admin, not Profile Settings | ### Header check behind a proxy Send the same token with both spellings and compare the status codes. Hyphen `200` plus underscore `401` means the proxy is eating the underscore header, not that the token is bad: ```bash for h in api-access-token api_access_token; do printf '%s -> ' "$h" curl -s -o /dev/null -w "%{http_code}\n" -H "$h: ${CHATWOOT_API_KEY}" \ "${CHATWOOT_BASE_URL}/api/v1/profile" done ``` Fix: use `api-access-token` everywhere (scripts, CI, webhooks that call back, CLI >= 0.7.0). If a legacy client cannot change, set `underscores_in_headers on;` in the nginx `http`/`server` block (for another proxy, look for its setting on underscore headers). ## Wrong scope / not found | Symptom | Cause | Fix | |---------|-------|-----| | `404` on every account call | Wrong `account_id` | Read it from the dashboard URL `.../app/accounts/{id}/...` | | `404` / HTML instead of JSON | Wrong base URL or trailing slash | Set `CHATWOOT_BASE_URL` to the origin only (e.g. `https://app.chatwoot.com`), no trailing `/` | | Self-hosted `404`/`502` | Reverse proxy or path prefix | Confirm the instance origin and that `/api/v1` is exposed | ## Request body errors | Symptom | Cause | Fix | |---------|-------|-----| | `422 Unprocessable` | Missing/invalid fields | Compare the body to the schema: `jq '.paths["<path>"].post.requestBody' openapi/application_swagger.json` | | Message sends but is empty/wrong type | Wrong `message_type`/`content_type` | Use `message_type: "outgoing"` (or `"incoming"`), `private: true` for notes | | Attachment ignored | Sent as JSON | Use `multipart/form-data` with `attachments[]` (see `pagination-errors.md`) | ## CLI issues | Symptom | Cause | Fix | |---------|-------|-----| | `401` on every command behind nginx/Caddy | CLI older than v0.7.0 sends the underscore header, which the proxy drops | Upgrade the CLI to v0.7.0 or newer | | Second command on the same conversation fails at once | v0.7.0 per-conversation write lock is held by another process | Wait for the other writer or re-read the conversation; don't retry in a loop | | `auth login` hangs/fails | Run in a non-TTY (CI/agent) | Don't script `auth login`; export `CHATWOOT_API_KEY` and keep `~/.chatwoot/config.yaml` (or pass `-a`) | | Agent can't parse output | Default text format | Pass `-o json` (or `-q`); never grep text output | | `convs` returns "too few" | Defaults to your open queue | Add `--assignee all` and the right `-s` status | | Labels got wiped | `label` replaces the set | Fetch existing first and merge; use `set -o pipefail` (see `cli-recipes`) | | Keyring error on login | No system keyring (headless Linux) | Use the `CHATWOOT_API_KEY` env var instead of the keyring | | Want to see the HTTP call | Debugging an odd result | Re-run with `-v` to print request/response | ## Webhook problems | Symptom | Cause | Fix | |---------|-------|-----| | Signature never matches | HMAC over parsed JSON | Compute HMAC-SHA256 over the **raw** body as `"{timestamp}.{raw_body}"`, compare to `X-Chatwoot-Signature` (`sha256=...`) | | No deliveries arrive | URL unreachable / not subscribed | Verify the endpoint is public + returns `2xx`; check `subscriptions` includes the event | | Bot replies in a loop | Reacting to its own messages | Only act on `message_type == "incoming"` | | Duplicate handling | Retried deliveries | De-duplicate on `X-Chatwoot-Delivery` | ## Rate limiting `429 Too Many Requests` → add exponential backoff, reduce concurrency, and batch reads with pagination instead of firing unbounded parallel requests. Limits differ between Cloud and self-hosted. ## When to escalate - Consistent `5xx` on Cloud → check https://status.chatwoot.com; on self-hosted check the Rails/Sidekiq logs. - Suspected token compromise → rotate the access token in Profile Settings immediately.
View on GitHub