Troubleshooting

Common issues.

Things that go wrong and how to fix them.


Issues

Daemon won't start

health.sh shows "daemon not running", port 3847 is not responding to requests.


Port 3847 is already bound by another process, Node.js version is below 22, or node_modules is missing or incomplete.


Check whether the port is already in use:

lsof -i :3847

Verify you're running Node.js 22 or newer:

node --version

Reinstall dependencies if the module directory looks stale:

npm install

If the daemon is managed by launchd, kick it:

launchctl kickstart -k gui/$(id -u)/com.assistant.daemon
"Cannot find module" errors

The daemon crashes on startup with a Cannot find module '...' error in the logs.


npm install was never run, or node_modules is stale after pulling changes. The dist/ directory may also be out of date.


Nuke node_modules and reinstall, then rebuild:

rm -rf node_modules && npm install && npm run build
SQLite errors on startup

SqliteError: no such column, no such table, or similar schema errors appear in the daemon logs immediately at startup.


The database schema is stale. This happens when a migration drops or renames a column but code in dist/ still references the old name. Also triggered by a test kithkit.db with an empty migrations table left over from development.


Delete the old database and let migrations recreate it from scratch:

rm kithkit.db && npm run build

Then restart the daemon. Migrations will run automatically on next start.

This deletes all stored memories, todos, and calendar entries. Export anything important before doing this. After migrations alter the schema, also grep dist/ for any removed column names — the compiled output may still reference them.

Claude Code CLI not found

claude: command not found when the daemon tries to spawn an agent or start a tmux session.


The Claude Code CLI isn't installed, or it's installed to a path that isn't in the daemon's PATH environment. Launchd-managed daemons inherit a minimal PATH that often excludes ~/.local/bin.


Install the CLI globally:

npm install -g @anthropic-ai/claude-code

Verify the install:

claude --version

If it's installed but the daemon can't find it, add the install location to your shell profile and update the daemon's plist to include the full path:

export PATH="$HOME/.local/bin:$PATH"
tmux session won't start or attach

"no sessions" error when running tmux attach, or the agent's tmux session fails to appear after startup.


The startup script didn't run, tmux crashed and cleaned up its socket, or tmux isn't installed.


Create the session manually:

tmux new-session -d -s comms1

Or re-run the startup script:

./scripts/start-tmux.sh

If tmux itself is missing, install it:

brew install tmux
Agent has no memory between conversations

The agent doesn't recall past conversations, previous tasks, or facts it was told before. Memory searches return nothing.


Vector search wasn't initialized at startup — enableVectorSearch() must be called in the extension's onInit hook. Also common: the ONNX model file hasn't downloaded yet.


Check daemon logs for enableVectorSearch errors or any mention of the ONNX model. The all-MiniLM-L6-v2 model (~23 MB) downloads automatically on first boot — the daemon needs outbound internet access for this. Once downloaded, it's cached and available offline.

Keyword search always works even without the ONNX model. If you're seeing nothing from keyword searches either, the memory store endpoint itself may not be receiving writes. Check that the extension is calling POST /api/memory/store correctly.

Telegram messages not being delivered

Agent doesn't respond to Telegram messages, or messages the agent sends never arrive. The bot shows as online but is non-interactive.


Webhook not registered or pointing to a stale URL, invalid bot token in config, or the daemon's public endpoint is unreachable from Telegram's servers.


Verify the daemon is healthy and the webhook is set:

curl http://localhost:3847/health

The daemon registers the Telegram webhook automatically at startup. If something got out of sync, a daemon restart re-registers it:

launchctl kickstart -k gui/$(id -u)/com.assistant.daemon

Also confirm the bot token in kithkit.config.yaml matches the token from @BotFather, and that your public endpoint URL is accessible from the internet.

Worker agents fail to spawn

"spawn failed" in orchestrator logs, or workers stay in queued status indefinitely and never transition to running.


Maximum concurrent workers reached with stale agents never cleaning up, or the Claude Code CLI isn't in the PATH that the daemon's spawn process inherits.


Check for stuck agents and kill any that are no longer active:

curl http://localhost:3847/api/agents

Kill a specific stuck agent by its ID:

curl -X DELETE http://localhost:3847/api/agents/:id

Stale npm test or claude subprocess trees can also fill up process slots. Periodically check for and kill orphaned workers:

pgrep -f "npm test" | xargs kill -9 2>/dev/null; true
Permission errors on macOS

Operation not permitted errors when the agent tries to read files, run shell commands, or access directories. Most common when the agent is trying to work with files in ~/Documents, ~/Downloads, or external drives.


macOS TCC (Transparency, Consent, and Control) is blocking file access for the terminal application or for processes launched by launchd.


Grant Full Disk Access to the terminal app and, if needed, to /usr/local/bin/node:

System SettingsPrivacy & SecurityFull Disk Access

Add your terminal application (Terminal.app, iTerm2, or whatever hosts tmux) to the allow list. If the daemon runs as a launchd service, you may also need to add the node binary itself.

Config changes not taking effect

You edited kithkit.config.yaml but the daemon is still behaving as if the old values are in effect.


Config is loaded into memory at startup and not re-read automatically on file change. The daemon needs to be told to reload it.


Hot-reload the config without restarting the daemon:

curl -X POST http://localhost:3847/api/config/reload

Or do a full daemon restart if the change affects the extension or scheduler initialization:

launchctl kickstart -k gui/$(id -u)/com.assistant.daemon