Skip to main content

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-project or remi --daemon.
  • Wrong port. Check if you customized the port with --port or REMI_PORT.
  • If you started with --local or --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) or ipconfig getifaddr en0 (macOS).
  • In wrapper mode, the WebSocket server may have silently failed to start. Check ~/.remi/remi.log for 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 --force on 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.log shows "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:

  1. Confirm Ollama is running: curl -s localhost:11434/api/tags
  2. Confirm the model is pulled: ollama list (look for gemma4:e2b or your configured model)
  3. Confirm Remi captured the main session lock: grep for [Hooks] Transcript from PreToolUse: claude=... in ~/.remi/remi.log. No match → see "Two daemons" above.
  4. Confirm the permission request is from the main session and not a subagent: events with agent_id set are deliberately filtered (see [Hooks] Dropped subagent PermissionRequest log lines).
  5. 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.