Troubleshooting
The failure modes you are most likely to hit.
The failure modes you are most likely to hit, roughly in the order people hit them.
Claude Code cannot reach the API
init points ANTHROPIC_BASE_URL at localhost. If Iris is not running,
Claude Code has nowhere to send requests. This is the single most common report, and the fix is
usually "start Iris".
Start Iris in any terminal and try again:
npx @zero-drift/iris
If you want Claude Code to work without Iris, remove the variable — see Uninstall. Iris on a different port than settings expect produces the same symptom; start it from the project directory and it re-points settings itself.
Iris starts but Claude Code does not connect
- Did you restart Claude Code? It reads
.claude/settings.jsonat session start. A session that was already open will not pick upinit. - Is it the same project? One instance serves the project it was started in. Check the Project name in the startup banner against the directory Claude Code is working in.
- Check the port. Compare
ANTHROPIC_BASE_URLin.claude/settings.jsonwith the Proxy URL in the banner.
The dashboard says "waiting for agent"
The proxy is up, but no traffic has reached it. Send one message in Claude Code. If nothing appears, work through the previous section — this is the same problem seen from the other end.
Claude Code stopped working after Iris exited
Expected, and the same root cause as the first section. Either restart Iris, or remove
ANTHROPIC_BASE_URL from .claude/settings.json and restart Claude Code.
Port 8787 is already in use
Iris tells you who has it. If it is another Iris instance on another project, it moves to the next free port and re-points this project's settings — restart Claude Code and carry on.
If you passed --port or set PROXY_PORT, Iris refuses rather than
moving, because an explicit port is never silently changed. Free the port or pick another:
lsof -nP -iTCP:8787 -sTCP:LISTEN
npx @zero-drift/iris --port 8801
Every tool call fails the hook
Iris prints this on startup when it sees it:
! Guard hook points at a path that no longer exists:
/path/to/old/bin/iris.mjs
Every tool call will fail this hook until it is re-pointed. Run:
npx @zero-drift/iris init
Hook commands are absolute paths, and paths move — npx resolves into a cache directory
that gets pruned and recreated under a new hash, a global install moves with the Node version, a
checkout gets relocated. Re-running init repairs it, and also drops a redundant duplicate
hook so it cannot run twice per call.
An Optimize change did not appear
- Did you press Publish changes? Toggling only stages; nothing is written until you publish.
- Did you restart Claude Code? The deny list applies from the next session, not the next turn.
- Is the old prefix still cached? A prefix already resident in cache keeps billing until its TTL expires. The saving shows on the next fresh prefix.
A tool disappeared and I need it back
Open Optimize, toggle it back on, publish, restart Claude Code. Or edit
.claude/settings.json directly and delete its entry:
{
"permissions": {
"deny": [/* remove the tool name here */]
}
}
If Claude has become oddly incapable — cannot read files, cannot run commands — check whether a Core tool ended up in the deny list. That is the usual cause.
Guard is asking too often
Read the rule name on the decision. high-consequence.unknown means no recognizer
matched the command, which is the intended behaviour for anything unrecognised — the alternative is a
denylist that silently allows what it has not been taught.
If the pattern is legitimate and repeated, widen the envelope deliberately in Guard rather than disabling the hook. If a common, safe command is being classified as unknown, that is worth an issue — recognizer coverage is exactly the kind of contribution that helps.
Guard denied something I actually need
Open Guard and read the rule. hard-deny.production and scope.filesystem
are the two that block outright.
- Path outside the project. Intended. If the work genuinely lives outside the project root,
run Iris from a directory that contains both, or widen
scope.filesystemin the envelope. - Production. Also intended. Widening this is a deliberate decision — edit the envelope and accept it, knowing what you have granted.
The envelope is a file. If the UI has you stuck, edit
~/.iris/projects/<id>/sessions/authority.json directly and restart the session.
How do I completely remove Iris?
See Uninstall — every change, in the order to undo it.