Skip to content

Troubleshooting

Common problems and how to fix them. Run chatwire doctor first — it surfaces 90% of setup issues automatically.

Diagnosis checklist

# 1. Check all permissions and service state
chatwire doctor

# 2. Check what's running
launchctl list | grep chatwire

# 3. Check the web server
curl -s localhost:8723/healthz

# 4. Tail live logs
chatwire logs -f

chatwire: command not found

Cause: ~/.local/bin is not on your PATH.

Fix:

python3 -m pipx ensurepath
# Then restart your terminal or:
source ~/.zshrc   # for zsh
source ~/.bash_profile  # for bash

Verify: which chatwire should return ~/.local/bin/chatwire.


Bridge starts but no messages appear

Causes (in order of likelihood):

  1. Full Disk Access not granted
  2. Automation → Messages not granted
  3. Whitelist is empty (no contacts configured)

Fix:

chatwire doctor

Look for ✗ on Full Disk Access or Automation → Messages. Grant the missing permission per macOS permissions, then restart:

launchctl kickstart -k gui/$(id -u)/dev.chatwire.bridge

If permissions are ✓ but messages still don't appear, check the whitelist: Settings → Whitelist in the web UI. A contact must be on the whitelist for their messages to be relayed.


Messages send from the web UI but don't arrive

Causes:

  • Messages.app is force-quit or unresponsive
  • Do Not Disturb or Focus mode is blocking sends on macOS (affects AppleScript in some cases)
  • Automation → Messages permission was revoked

Fix:

# Check the Automation permission
chatwire doctor

# Look at bridge logs for AppleScript errors
chatwire logs --service bridge -f

Restart Messages.app if it's unresponsive. On macOS 15 Sequoia with SMS/RCS contacts, see the compatibility notes.


Web UI doesn't load

Step 1: Check the web agent:

launchctl list | grep chatwire.web
# Should show a line with the dev.chatwire.web label

Step 2: Try the health endpoint:

curl localhost:8723/healthz
# Should return {"ok":true,...}

Step 3: Check web logs:

chatwire logs --service web -f
# or directly:
tail -f ~/Library/Logs/chatwire/web-stderr.log

Common causes:

  • Port 8723 is taken by another process: lsof -i :8723
  • The web agent failed to load: launchctl list dev.chatwire.web — a non-zero exit code in the output means it crashed
  • FastAPI failed to import: check the log for ModuleNotFoundError

Reload the web agent:

launchctl kickstart -k gui/$(id -u)/dev.chatwire.web

Wrong Python warning

WARNING: chatwire is running under a Python whose base prefix is
  /opt/homebrew/...
which is not python.org's framework Python.

Cause: pipx resolved to Homebrew Python instead of python.org Python.

Fix: Reinstall with the explicit python.org binary:

pipx uninstall chatwire
pipx install \
  --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
  chatwire

Then re-grant Full Disk Access and Automation → Messages to the new binary path (shown in chatwire doctor).


Permission grants don't stick after Python upgrade

Cause: Upgrading Python (e.g., 3.12 → 3.13) installs a new binary at a new path. TCC grants bind to the old path.

Fix:

  1. Run chatwire doctor to see the new binary path
  2. Open System Settings → Privacy & Security → Full Disk Access
  3. Remove the old entry (toggle off, then -)
  4. Add the new path with +
  5. Repeat for Automation → Messages
  6. Restart the bridge

Agent not loading (already loaded vs real errors)

The chatwire install-agents command runs launchctl load -w. "already loaded" in the output is harmless — the agent is running.

Any other error from launchctl means the plist is malformed or the binary path in the plist doesn't exist. Check the plist:

cat ~/Library/LaunchAgents/dev.chatwire.bridge.plist

Look for ProgramArguments — it should point to your actual venv Python and to bridge.py. If the path is wrong, re-run:

chatwire install-agents

"Port 8723 already in use"

Cause: Another process (or an old chatwire instance) is using the port.

Find the process:

lsof -i :8723

Change the port in ~/.chatwire/config.json:

{
  "web": {
    "port": 8724
  }
}

Then restart: launchctl kickstart -k gui/$(id -u)/dev.chatwire.web


chatwire doctor shows stale binary after reinstall

If you reinstalled chatwire with a different Python, the plist still points to the old binary. Reinstall the agents:

chatwire install-agents

This re-renders the plists with the new binary path.


Contacts show as phone numbers, not names

Cause: Contacts permission not granted, or Contacts.app database is in an unusual location.

Fix:

  1. Open System Settings → Privacy & Security → Contacts
  2. Toggle on your Python binary
  3. Restart the bridge: launchctl kickstart -k gui/$(id -u)/dev.chatwire.bridge

On macOS 13+, Full Disk Access covers the Contacts database path, so this sometimes resolves itself once FDA is granted.


TCC reset (nuclear option)

If permissions are completely stuck:

# Clears ALL Full Disk Access grants (not just chatwire)
tccutil reset SystemPolicyAllFiles

# Clears ALL Automation grants
tccutil reset AppleEvents

After resetting, re-grant both permissions to the chatwire Python binary. Note this affects all apps on your Mac that have these grants.


Checking logs directly

All log files are in ~/Library/Logs/chatwire/:

File Contents
stderr.log Bridge process output
web-stderr.log Web process output
keepawake-stderr.log Keepawake process output

Structured JSON logs in ~/.chatwire/:

File Contents
chatwire.jsonl Bridge and web structured log (also viewable in the Log Viewer at /logs)
chatwire.1.jsonl Previous log (auto-rotation)

Still stuck?

Open an issue with: - Your macOS version (sw_vers) - Your Python version and binary path (chatwire doctor output) - The install method (pipx / Homebrew / uv) - The relevant log lines from chatwire logs -f