Skip to main content
By the end of this page you will be able to tell, in a few commands, whether a problem sits in the processes, the channel, routing, permissions or the model provider, and to restart Ravi without leaving pieces behind.

First checks

What to look for:
  • ravi daemon status does not list the Slack runner ravi-channels. Use ravi channels status: a healthy runner shows health: ready and the Slack adapter as connected. health: stopped (not_running) means it is not online in PM2: never started, stopped or crashed.
  • runtime: drifted means the CLI, daemon and runner run different versions. Run ravi update, which installs the configured channel and restarts the managed processes. On @next, run ravi update --next unless you already used --next once; until then, a plain ravi update installs latest.
  • omni-nats: not managed by PM2 is expected if you run your own nats-server.
  • On a Slack-only install the daemon logs Omni not configured — no channel support and Creating gateway without omni — channel delivery will fail. Slack replies go through the channel runner, so these lines are harmless there.

ravi doctor

Some findings are false alarms in this version: The doctor does not check NATS, Omni, the channel runner, Slack tokens or provider credentials. A clean report does not prove a channel works.

The agent did not answer

Start by finding out whether the message reached a session:
If a session exists, read its trace. Otherwise, match what you see:
Do not use ravi instances pending approve with Slack IDs: for a channel it stores a broken group: pattern made of the ID’s digits, and for a member it can create a stray phone contact. Add the route yourself with ravi instances routes add as shown above. To see which route wins for a chat, run ravi routes explain <instance> <pattern>.

The agent answered but cannot use tools

The agent always replies, but what it may do depends on who is talking. A sender that Ravi cannot link to a contact gets zero capabilities. To see what is allowed and watch denials live:
Permissions covers profiles, contact tags and governed chats.

Claude answers but its SSH-side Ravi CLI fails

For an agent configured with remote, the SSH user has its own home and local Ravi state. Forward both the issued RAVI_CONTEXT_KEY and RAVI_GATEWAY_URL so its CLI authenticates to the actual daemon instead of opening an empty local database. Do not give the SSH user access to the operator’s database. The SSH launcher derives a gateway URL for loopback agents when the daemon HTTP server is enabled with RAVI_HTTP_PORT (or RAVI_WEBHOOK_PORT). For another host, configure an explicit URL reachable from that host. An explicitly configured RAVI_GATEWAY_URL takes precedence. Check command -v ravi and ravi --version as the SSH user. That installation needs a version compatible with the daemon and its production dependencies. An old wrapper can select a stale checkout despite a current package being installed elsewhere. With the issued context and gateway, verify:
If local Claude accepts a token but SSH Claude returns 401, check the launcher before replacing the credential. Older launchers used literal \\n between exports, corrupting the forwarded token. After correcting the launcher and validating the token through SSH, clear the stale pool health entry with ravi runtime credentials reset-health <credential-id> --json. The full-access runtime profile includes admin system:*; explicit read-only Page capabilities listed beside it do not reduce that profile to read-only. Inspect effective authority before adding grants.

Read the session trace

The trace is stored in ~/.ravi/ravi.db and records every step of a session, from the incoming message to delivery.
Read it top to bottom and find the last row that is there: Slack messages enter the trace at prompt.published; Slack’s routing decisions are in ravi channels logs. Common --explain findings: --show-system-prompt, --show-user-prompt (with --turn) and --raw print full prompts and payloads. They can contain private content, so replace real ids, phone numbers and prompts with placeholders before sharing a trace. For a session that is running right now, ravi sessions debug <name> tails its live events for 60 seconds.

Pages and Bases

Publish pages and Interactive pages with Bases cover these flows in depth.

Inspect NATS and JetStream

If the daemon repeatedly exits while ensuring RAVI_EVENTS, inspect the NATS log for 10047: insufficient storage resources available and check disk space with df -h. A connected Slack runner does not prove the daemon is running. Free only verified disposable caches, then restart the managed NATS server (pm2 restart omni-nats) so its storage budget is recalculated. Confirm that RAVI_EVENTS restores and the daemon reaches Daemon ready; preserve the JetStream data and Ravi databases. This is operator recovery, not automatic cache deletion by Ravi. Ravi needs NATS with JetStream at NATS_URL (default nats://127.0.0.1:4222). These streams exist on a typical install: Omni also creates IDENTITY, MEDIA, ACCESS, SESSION, CUSTOM, SYSTEM and AGENT. A KV_ravi-leader stream holds the leader lock that decides which daemon runs cron and heartbeat. Ravi’s own commands cover most needs:
replay reads stored messages (default: the last 15 minutes from every non-KV stream). Include RAVI_EVENTS to see tool activity, responses, delivery and aborts; MESSAGE alone only has traffic from Omni channels such as WhatsApp. With the nats CLI you can look at the server directly:
If a WhatsApp consumer is stuck, delete it and restart the daemon. Ravi recreates it starting from new messages, so anything still pending is skipped, not replayed:
WhatsApp history-sync messages (ingestMode: "history-sync") are stored but never run a turn.

Restart cleanly

  • -m is required: without it the restart fails with Flag -m é obrigatória. The message is passed to the main agent.
  • Restart the daemon after editing ~/.ravi/.env or changing provider credentials.
  • Restart the channel runner after ravi channels create or set, after changing a Slack secret, and after a daemon restart if ravi channels status is not ready. Routes and instances reload on their own.
  • The runner must run the same Ravi version as the daemon. If ravi channels start refuses because of a bundle mismatch, run ravi update first (ravi update --next on @next, as above).
  • Bring things up in order: NATS (Omni or your own nats-server), then the daemon, then the channel runner.
omni stop removes both omni-api and omni-nats from PM2, which takes Ravi’s NATS down with it. To restart Omni’s NATS alone, use pm2 restart omni-nats.