Troubleshooting
This page collects the failure modes that come up most often when running
kanros against real provider endpoints, real caches, and real configs.
Each entry pairs the user-visible symptom with the diagnostic command
that confirms the root cause, plus the fix.
If you hit a problem that isn't covered here, please email support@kanros.dev with the diagnostic output — we'd rather extend this page than have you debug it twice.
kanros run hangs (no output, no progress)
Symptom. kanros run -c kanros.yaml prints the run header but never
emits a cell result. No timeout fires, no error surfaces. Ctrl-C exits
cleanly, so the process isn't deadlocked — it's blocked on I/O.
In nearly every case this is the configured provider's network call sitting in a TCP retry loop because the endpoint, the API key, or the local DNS is wrong.
Diagnose.
# Re-run with the structured tracing layer cranked up. The provider
# emits a span around every outbound HTTPS call; if you see the span
# open but never close, the provider is the culprit.
RUST_LOG=kanros_providers=debug,kanros_runner=info \
kanros run -c kanros.yaml --concurrency 1
If the trace shows the request going out but no response, hit the provider's health endpoint directly:
# Substitute the base URL from your provider config.
curl --max-time 5 -sS -o /dev/null -w '%{http_code}\n' \
https://api.openai.com/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
A non-2xx (or a curl timeout) confirms the issue is upstream of kanros.
Fix. Verify the provider.config.base_url field in your YAML, check
that the API key has not been rotated, and confirm no corporate proxy
is intercepting outbound HTTPS. For local providers (ollama,
llama-cpp, lm-studio) confirm the daemon is up on the configured
port.
Cache permission denied
Symptom. kanros run aborts during cache initialization with
Error: Permission denied (os error 13) and a path under
~/.cache/kanros/. This typically happens after running kanros under
sudo once: the cache directory then ends up owned by root, and
subsequent un-privileged runs cannot open the SQLite file.
Diagnose.
# Inspect ownership and permissions on the cache root.
ls -ldn ~/.cache/kanros ~/.cache/kanros/*.sqlite 2>/dev/null
A line showing UID 0 (root) when you're running as a regular user is
the giveaway.
Fix. Either chown the directory back to your user, or wipe the cache and let kanros recreate it with the correct mode:
sudo chown -R "$(id -u):$(id -g)" ~/.cache/kanros
# — or —
rm -rf ~/.cache/kanros && kanros cache stats
The second form is preferred when you don't know what else might be
inside; kanros cache stats rebuilds the directory at the correct
mode (0700) and seeds an empty SQLite file.
Schema validation fails on valid YAML
Symptom. A kanros.yaml that worked yesterday now fails with
additionalProperties: ... or unknown variant ..., even though the
file is unchanged and parses as valid YAML in your editor.
This is almost always schema drift: you upgraded kanros (or built
from a newer commit) and the embedded JSON Schema picked up a new
required field, or renamed a variant of AssertionType.
Diagnose.
# Print the schema your installed binary believes in, and validate
# the config against it explicitly.
kanros schema > /tmp/kanros.schema.json
kanros validate --config kanros.yaml --explain
--explain prints the JSON pointer at which validation failed, which
makes the divergence point obvious. Cross-reference against the live
schema (kanros schema) and the
Configuration reference.
Fix. Either pin to the previous kanros release until you've migrated the config, or regenerate any tooling (IDE plugins, CI lints) that consumes the schema:
kanros schema > tooling/kanros.schema.json
git add tooling/kanros.schema.json
If you maintain a fork of the config schema, regenerating against the new binary is the canonical fix — kanros's schema is the source of truth.
API key not found (keyring lookup)
Symptom. Provider initialization fails with
Error: no API key for provider 'openai' even though OPENAI_API_KEY
is set in your shell, or vice versa: the env var is unset but you
expect kanros to read from the OS keychain.
kanros resolves credentials in a fixed order, and kanros auth writes
to the OS keychain (Keychain on macOS, Secret Service on Linux, Windows
Credential Manager on Windows). The lookup order is:
- The explicit
api_keyfield in the provider config (rare; usually only for tests). - The provider-specific env var (
OPENAI_API_KEY,ANTHROPIC_API_KEY, …). - The OS keychain, queried via the
keyringcrate under the service namekanrosand an account named after the provider id.
If step 2 wins, step 3 is never consulted — even if the env var is empty-string.
Diagnose.
# Show what kanros sees, without exposing the key itself.
kanros auth list
This prints the resolution result per provider (env, keyring, or
missing). For an interactive trace:
RUST_LOG=kanros_cli::auth=debug kanros auth check openai
Fix.
- If you intended to use the keyring, unset the env var:
unset OPENAI_API_KEY kanros auth set openai - If you intended to use the env var, make sure it's exported, not just
set in the current shell scope:
export OPENAI_API_KEY="sk-..." - If
kanros auth listshows the key asmissingeven after you rankanros auth set, the OS keychain itself rejected the write. On headless Linux this usually meanssecret-serviceisn't running — startgnome-keyring-daemon --components=secretsor fall back to env vars.
See also
- Configuration reference — the schema this page's errors come from.
- Cache commands — the
stats,clear, andinspectsubcommands referenced above. - init, completions, auth — the
kanros authsubcommand surface in full.