Troubleshooting
Almost every “Ony.ai never rings” problem collapses into the hook’s silent fail-safe: when something is
wrong, the gate steps aside rather than blocking your agent, so you just see no call. ony doctor
makes each cause visible.
Start here: ony doctor
Section titled “Start here: ony doctor”ony doctorIt prints one actionable line per check and exits non-zero if anything fails. Run it from the project
directory whose Claude wiring you want checked (or pass --project <repo>). The checks cover:
- config -
~/.ony/config.jsonexists, parses, and (on POSIX) is owner-only. - enrollment - the device id, token, and server URL are present.
- decision key - the per-device key used to verify signed verdicts is present. Without it, every phone verdict fails verification and downgrades to “ask”.
- server - the Ony.ai server is reachable, with a compatible signing scheme.
- clock - your local clock is within ~60s of the server’s.
- signing - a sign-and-verify roundtrip works locally.
- call readiness - a real carrier is configured and you have a verified phone number.
- mode - the current
/onymode. - claude hooks - the project’s
PreToolUsegate is registered, each hook entry has a >60s timeout, and the baked interpreter path and package root still exist.
Fix the failing lines top to bottom, then re-run. Most sections below map directly to one check.
Ony.ai never calls
Section titled “Ony.ai never calls”Not enrolled. ony doctor says config or enrollment is missing. Fix:
ony enroll --url <your-ony-url> --email <you>Wrong /ony mode. In off, Ony.ai does nothing. In on, it phones only for high-risk actions, so
routine steps never ring. Check with ony status; switch with ony away (every actionable step) or
ony on (high-risk only). See the modes page.
Server unreachable. The gate cannot raise a handoff, so it fails safe and steps aside. Confirm
the server is up and --url points at it. For a self-hosted server, bring it back with
docker compose up -d (or ony up for the local Lite server).
Mock carrier, so no phone rings. Out of the box the server uses the built-in mock carrier: handoffs surface in the dashboard (Approve / Deny), but no phone rings. Add a real provider under Settings -> Integrations -> Telephony and verify your number. See carrier setup.
No verified phone. Even with a real carrier, ony away will not ring anyone until you verify a
contact number in the dashboard (Settings -> Profile). ony doctor’s call-readiness check flags this.
Missing decision key. If enrollment did not return a decision key, every verdict fails signature
verification and silently downgrades to “ask”. Re-enroll to receive one: ony enroll.
Clock skew. A signed verdict expires about 60 seconds after it is signed. If your local clock is
off by more than that, every verdict looks expired and each decision downgrades to “ask” - so the
call may even connect but the answer never lands. Sync your system clock; ony doctor’s clock check
shows the drift.
Stale hook wiring. If the venv or package moved after install, the baked interpreter path or
package root in .claude/settings.json no longer resolves and the hook cannot run. ony doctor
flags this; fix it by re-running ony hooks install --project <repo> from the right environment.
The call connects but you hear dead air
Section titled “The call connects but you hear dead air”This usually means the server can place a call but the carrier’s webhook path back to the server is
not signing correctly, so the call connects without instructions. ony doctor’s call-readiness
check reports a carrier that is “not fully configured (missing credentials or webhook signing)”.
Recheck the carrier’s credentials and webhook signing secret in Settings -> Integrations against
your provider, and confirm the webhook URL is reachable from the carrier. See
carrier setup.
Ony.ai rings too much
Section titled “Ony.ai rings too much”You are almost certainly in away mode, which phones for every actionable step. That is by design
for remote control. When you are back at the keyboard, switch to high-risk-only calls:
ony here # or: ony onAllowlisted commands do not ring
Section titled “Allowlisted commands do not ring”This is intentional, and it holds in every mode. Ony.ai composes with Claude Code’s own
permission surface by pure inheritance: it rings exactly when Claude itself would stop and prompt
you. Work you already pre-authorized - allowlisted commands, accept-edits, bypass-permissions -
never prompts Claude, so it never reaches the gate and never rings, in on or in away alike.
Switching to away widens the calls to every ask Claude would have shown you, not to steps
Claude was already going to run silently. If you want a phone call for a command, take it off the
allowlist - that is the phone-level kill switch. The one exception is the opt-in headless install
(ony hooks install --headless), whose pre-execution PreToolUse gate decides independently of
Claude’s dialogs. More on this composition is in how the gate works and on
the modes page.
Still stuck?
Section titled “Still stuck?”Re-run ony doctor after each change, and check the dashboard’s session and audit views to see
whether handoffs are being raised at all. Carrier-specific setup lives in
carrier setup; how gating composes with your agent is on the
modes page.