Troubleshooting
Solutions for common Remi issues.
Startup Issues
"No identity found"
No identity found. Run "remi keygen" first.
Remi requires an Ed25519 identity before it can start. Generate one:
remi keygen
"Identity file is empty"
Identity file is empty. Run "remi keygen --force" to regenerate.
The identity file at ~/.remi/identity.json exists but is empty or corrupted. Regenerate it:
remi keygen --force
"Identity is encrypted and REMI_PASSPHRASE is not set"
Identity is encrypted and REMI_PASSPHRASE is not set.
Set REMI_PASSPHRASE or use an unencrypted identity.
Your identity was created with remi keygen --passphrase and is encrypted. You have three options:
- Set the passphrase:
export REMI_PASSPHRASE="your-passphrase"then retry - Remove the passphrase:
remi keygen --decrypt(keeps the same keypair; no re-authorization needed) - Regenerate unencrypted:
remi keygen --force(creates a new keypair; clients must re-authorize)
"Failed to unlock identity"
Failed to unlock identity: ...
Wrong passphrase?
The passphrase provided does not decrypt the identity file. If you forgot the passphrase, generate a new identity with remi keygen --force and re-authorize all clients.
Connection Issues
"Cannot connect to daemon"
The Remi web app cannot reach the WebSocket server.
Possible causes:
- Remi is not running. Start it with
remi my-projectorremi --daemon. - Wrong port. Check if you customized the port with
--portorREMI_PORT. - If you started with
--localor--bind localhost, the daemon only accepts connections from the same machine. Use the default bind (0.0.0.0) to accept connections from other devices. - Firewall blocking the port. Ensure port 18765 (or your custom port) is accessible.
- Wrong IP address. Verify the server's IP with
hostname -I(Linux) oripconfig getifaddr en0(macOS). - In wrapper mode, the WebSocket server may have silently failed to start. Check
~/.remi/remi.logfor startup errors.
"Connection timeout"
The WebSocket connected but the handshake did not complete within 10 seconds.
Possible causes:
- The server is under heavy load or unresponsive.
- Network latency is too high for the timeout. Try a direct connection instead of relay.
- The server does not recognize the protocol version.
Port Already in Use
EADDRINUSE: port 18765 already in use
Another process is using the port. Either stop that process or use a different port:
remi --port 9001 my-project
In wrapper mode, port conflicts are logged to ~/.remi/remi.log silently and Claude continues normally.
Authentication Issues
"AUTH_REQUIRED" / "UNKNOWN_KEY"
The server requires authentication but does not recognize the client's public key.
Solution: Authorize the client's key on the server:
remi authorize client-key.json --label "Device Name"
See the Authentication Guide for full setup instructions.
"INVALID_SIGNATURE"
The client's signature verification failed.
Possible causes:
- The client's private key does not match the authorized public key. Re-export and re-authorize.
- The identity file is corrupted. Generate a new one with
remi keygen --forceon the client.
"Server fingerprint changed"
The client previously connected to this server and stored its fingerprint. The fingerprint no longer matches.
Possible causes:
- The server regenerated its identity (e.g., ran
remi keygen --force). This is expected. - A man-in-the-middle attack is changing the server's identity.
Solution: If you trust the server's new identity, clear the old fingerprint in the Remi web app under Settings > Known Hosts. Then reconnect; the new fingerprint will be stored.
"Server did not provide mutual authentication signature"
The server sent an auth result without signing the challenge.
Possible cause: Protocol mismatch. Ensure both server and client are running the same version of Remi.
Session Issues
"No active sessions found"
remi attach found no running sessions.
Solution: Check if the daemon is running:
remi ls
If nothing is listed, start a new session with remi my-project.
"Session has no Claude session ID"
remi --resume cannot resume because the session exited before Claude reported its session ID.
Solution: Start a new session instead:
remi my-project
Ambiguous Session ID
remi attach abc matches multiple sessions.
Solution: Provide a longer prefix:
remi attach abc12345
Hooks and auto-approve
Two Remi daemons in the same directory
Running remi --auto-approve (or plain remi) in two terminals open to the same project directory causes both daemons to stop processing hook events. Symptoms:
- No GPU activity even when you expect auto-approve to run
- Questions do not appear on your phone
~/.remi/remi.logshows "Event bridge active" but nothing else
Cause: both daemons write their hook URL into the same .claude/settings.local.json. Each daemon sees the other as a sibling and refuses to lock onto a session to avoid cross-session hijacking. The check is cached — killing the extra daemon does not unblock the remaining one.
Workarounds:
- Run only one Remi daemon per working directory.
- If you need a second session in the same project, open the other terminal in a git worktree or a different path.
- If you already hit the lockup, kill both daemons and restart a single one.
Tracked in issue #321.
Stale session after Claude restart
If Claude Code exits and restarts inside the same Remi-managed PTY, Remi detects the new session_id and re-locks. This is normal and you should see:
[Hooks] Claude restart detected (ended=false): <old-id> -> <new-id>
in ~/.remi/remi.log. If instead you see events being dropped as foreign ([Hooks] Dropped foreign ...), the classifier is seeing the new session as coming from a subagent rather than a restart. This can happen if Claude exits very quickly without emitting SessionEnd. Restart Remi to clear the stuck state.
"No GPU spike" with auto-approve enabled
Order of checks:
- Confirm Ollama is running:
curl -s localhost:11434/api/tags - Confirm the model is pulled:
ollama list(look forgemma4:e2bor your configured model) - Confirm Remi captured the main session lock: grep for
[Hooks] Transcript from PreToolUse: claude=...in~/.remi/remi.log. No match → see "Two daemons" above. - Confirm the permission request is from the main session and not a subagent: events with
agent_idset are deliberately filtered (see[Hooks] Dropped subagent PermissionRequestlog lines). - For deeper inspection, restart with
REMI_HOOK_DEBUG=1 remi --auto-approve; every raw hook POST is written to~/.remi/hook-diag.jsonl.
Phantom ❯ 1 typed into Claude Code chat
Fixed in Remi 0.5.1-dev.3. Earlier versions mis-routed subagent/team permission requests through auto-approve and injected "1" into the main PTY, which landed in your chat input prompt. If you see this on 0.5.1-dev.3 or later, please file an issue with the ~/.remi/remi.log excerpt and (if possible) a REMI_HOOK_DEBUG=1 capture.
Logs
Remi logs to ~/.remi/remi.log in wrapper mode (when you run remi or remi new directly) and ~/.remi/daemon.log in daemon mode (remi start, remi --daemon, or the installed service). Check these files for detailed error information:
tail -f ~/.remi/remi.log # wrapper mode
tail -f ~/.remi/daemon.log # daemon mode
If the log file does not exist or is empty, Remi may not have been able to create it. Verify that ~/.remi/ exists and is writable.
For hook event debugging, set REMI_HOOK_DEBUG=1 before starting Remi; every raw hook POST goes to ~/.remi/hook-diag.jsonl.