Troubleshooting
Common issues and how to resolve them.
First Steps
For any issue, start with:
adjutant doctor
This checks dependencies, credentials, file permissions, and service state. It's read-only and won't modify anything.
If doctor reports problems:
adjutant setup --repair
Repair mode detects what's broken and fixes it.
Listener Issues
Listener won't start
Symptoms: adjutant start exits silently or reports an error.
Check:
adjutant status
Common causes:
| Cause | Fix |
|---|---|
KILLED lockfile exists | Run adjutant startup (not adjutant start) |
| Another listener already running | Run adjutant stop first, then adjutant start |
| Missing credentials | Check .env has TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID |
| LLM backend not found | Install OpenCode or Claude Code CLI and ensure it's on PATH |
Important: adjutant start will refuse to start if a KILLED lockfile is present. Use adjutant startup for recovery -- it clears the lockfile, restores crontab, and starts fresh.
Bot doesn't respond to messages
Check in order:
- Is the listener running?
adjutant status - Is it paused? Look for
PAUSEDin the status output. Runadjutant resume. - Is the chat ID correct? The bot only responds to the chat ID in
.env. - Check the log:
adjutant logs-- look for errors or "rejected unauthorized sender" - Rate limited? Adjutant limits to 10 messages per 60 seconds by default.
Listener crashes repeatedly
Check state/adjutant.log and state/listener.stderr.log for error details. Common causes:
- Invalid bot token (Telegram returns 401)
- Network connectivity issues
- LLM backend process crashes
If using LaunchAgent (macOS), the service will auto-restart. Check crash frequency with:
adjutant logs
KILLED State
How to recover
adjutant startup
This clears the KILLED lockfile, restores crontab from backup, re-syncs schedules, starts the listener, and sends a recovery notification.
What triggered the kill?
Check the log around the time of the kill:
adjutant logs
Look for [control] Emergency kill entries.
Scheduling Issues
Cron jobs not firing
- Verify crontab is installed:
crontab -l - Check if jobs are enabled:
adjutant schedule list - Re-sync:
adjutant schedule sync
"opencode/claude not found on PATH" in cron
Cron runs with a minimal PATH (/usr/bin:/bin), which typically excludes
directories like /opt/homebrew/bin where your LLM backend binary is installed. Adjutant
installs cron entries with a minimal explicit PATH that includes standard system
paths plus common package-manager locations, so re-syncing usually fixes this:
adjutant schedule sync
As a fallback, you can set the binary path explicitly:
# For OpenCode:
export OPENCODE_BIN=/opt/homebrew/bin/opencode
# For Claude Code CLI:
export CLAUDE_CODE_BIN=/usr/local/bin/claude
macOS Full Disk Access
On macOS, cron needs Full Disk Access to run scripts that access files outside standard directories.
Fix: System Settings > Privacy & Security > Full Disk Access > add /usr/sbin/cron
Jobs fire but produce no output
Check the job's log file (shown in adjutant schedule list). The log path is defined in the schedule's YAML config.
Model / AI Issues
"Model not found" errors
The configured model may not be available in your backend setup. Check:
adjutant status
Look at the current tier mapping. Switch to a known working tier:
/model cheap
Model switch doesn't persist
Model changes via /model are stored in state/telegram_model.txt as a tier name (cheap, medium, or expensive). They persist across restarts but not across adjutant kill + adjutant startup (which resets state). Set the default model in adjutant.yaml instead:
llm:
models:
cheap: "anthropic/claude-haiku-4-5"
Responses are very slow
- Check which tier is active with
/model-- expensive tiers are slower - Switch to a cheaper model:
/model cheap - Check if your backend is healthy:
opencode --versionorclaude --version
Knowledge Base Issues
KB query returns empty or errors
- Check the KB exists:
adjutant kb list - Check KB info:
adjutant kb info <name> - Verify the KB path exists on disk
- Try a direct query:
adjutant kb query <name> "test question"
KB not auto-detected in chat
The agent uses KB names and descriptions to detect relevance. Improve auto-detection by giving your KB a descriptive description field in knowledge_bases/registry.yaml.
Rate Limiting
"Slow down" messages
Adjutant limits to 10 messages per 60 seconds by default. Wait a minute and try again. This protects against accidental message floods and excessive API usage.
File Permission Issues
adjutant setup --repair
Repair mode checks and fixes:
- CLI executable permissions
- Directory permissions
- Missing directories
Getting More Help
- Check the commands reference for correct usage
- Read
state/adjutant.logfor detailed error information - Run
adjutant doctorfor a comprehensive health check - Check the GitHub issues