Troubleshooting¶
!!! info "TL;DR" Most CLI errors map to one of six exit codes. This page covers the failure modes that aren't obvious from the error text alone: 401 vs 403, the 422 unrecognized-key error, NO_COLOR, and rate limits.
401 vs 403¶
survey, question, and trigger commands call the same MCP tool endpoint and treat 401 and 403 the same way: both exit with code 3 (AUTH). The distinction still matters for diagnosis.
401, invalid or missing credential. You saw one of these:
Missing or invalid Authorization header. Use: Bearer pk_live_..., no credential was resolved at allInvalid API key, the key doesn't match anything on the serverAPI key has expiredInvalid or expired session token/Session token has been revoked, a cached session token (see Authentication) was rejected; the CLI retries once with yourpk_*key automatically, so this message means thepk_*key itself failed too
Fix: run canviq auth login, or check that CANVIQ_API_KEY is set and correctly copied (no trailing whitespace, no truncation from a shell quoting issue).
The most common cause of Invalid API key specifically: the key was not generated from Settings → Agents (/admin/settings/agents). An SDK key or a key created via the generic API Keys wizard has the same pk_live_/ pk_test_ look but no agent attached to it, and every canviq command rejects it. See Authentication → Getting an agent-backed key.
403, valid credential, not authorized. You saw one of these:
Agent is not active, the agent behind this key was suspended; contact your org adminInsufficient permissions to invoke this tool./ a message naming a missing scope, the key doesn't have the scope the command needs (for example,surveys:writeforquestion create). Regenerate the key with the required scopeAccess denied, the request came from a blocked source
canviq survey commands show shorter first-party copy for both cases (Not authenticated... / ...does not have the required scope...); question and trigger commands show the server's message directly. Either way, the exit code is 3.
canviq audit-logs is the one command that does not follow this pattern: it calls a separate REST endpoint (not the MCP tool endpoint) and only maps 403 to exit code 3. A 401 from that endpoint falls through to the generic Error: unexpected response from API (HTTP 401). message at exit code 1, not 3. See Audit Logs for the rest of that command's error handling.
422 unrecognized-key errors¶
POST /api/mcp/tools (the endpoint every survey, question, and trigger command calls) validates its request body against a strict schema: only tool and arguments are allowed at the top level. A request with any other top-level key, most commonly a leftover input key from an older client contract, is rejected with a 422 response naming the offending key directly, for example:
The shipped CLI always sends the correct { tool, arguments } shape, so you will not see this from canviq itself. It shows up if you or an agent call POST /api/mcp/tools directly with a hand-built request body. The CLI's shared error handling doesn't special-case 422; it falls into the generic 4xx bucket and exits with code 1 (GENERAL), not a dedicated code.
Exit code contract¶
The CLI's exit codes are the authoritative script-facing contract. Full table and examples: Scripting and CI → Exit codes. The exit-code definitions live in the public canviq-cli source.
| Code | When you'll see it in practice |
|---|---|
0 | Success, including "insufficient responses" on survey pmf-score |
1 | Network errors, malformed server responses, 422s, and any error path a command doesn't map to a specific code |
2 | A flag is missing, malformed, or out of range, checked before any network call |
3 | 401 or 403 from the MCP tool endpoint (see above) |
4 | The requested survey, question, or trigger ID doesn't exist |
5 | Rate limited, see below |
NO_COLOR¶
Setting NO_COLOR to any non-empty value disables ANSI color in table output, including NO_COLOR=0. The check is a truthiness test on the environment variable, not a comparison against "0" or "false". To restore color, unset the variable entirely:
Setting it to an empty string (NO_COLOR=) also restores color, an empty string is falsy, so this is indistinguishable from unset. Color is only ever shown on a TTY in the first place; --json, --quiet, and non-TTY output (piped, redirected, CI) never include color regardless of NO_COLOR.
429 rate limits¶
Two independent rate limiters can return 429, both map to exit code 5 and both include a Retry-After header that the CLI prints.
MCP tool endpoint (survey, question, trigger commands). The limit depends on your agent's assigned tier: 30 requests/minute on the default (readonly) tier, 300/minute on growth, 1000/minute on scale. Contact support to raise your tier if you're hitting this in normal usage.
Audit log endpoint (audit-logs command). Fixed at 60 requests/hour regardless of tier. See Audit Logs.
For a retry loop pattern, see Scripting and CI → Handling rate limits.
Report a bug or get help¶
Hit something this page doesn't cover? File it in the public canviq-cli issue tracker. Include the command you ran, the full output, the exit code, and your CLI version from canviq --version. That is enough to reproduce most problems without a back-and-forth.