Troubleshooting¶
Quick fixes for common Batty issues.
batty start fails: no team config found¶
Cause: No .batty/team_config/team.yaml in the project.
batty init # scaffold team config
batty start fails: session already exists¶
Cause: A previous session wasn't stopped.
batty stop # stop existing session
batty start # start fresh
tmux version error on startup¶
Cause: tmux is too old or missing.
tmux -V # check version
Recommended: >= 3.2. Minimum: 3.1. Below 3.1 is not supported. Upgrade tmux and retry.
kanban-md not found¶
Cause: kanban-md is not installed or not on PATH.
cargo install kanban-md --locked
Ensure ~/.cargo/bin is in your PATH.
DevSpace AIM catalog entries duplicate across launches¶
Cause: AIM currently soft-deletes packages on uninstall. Old
~/.aim/packages/*/eventId-* directories can survive across DevSpace launches,
so later Batty-launched engineer sessions can see duplicate package/catalog
entries.
Batty does not currently ship the affected DevSpace startup hook in this repo.
If your environment uses an external bootstrap script such as
blueprint_startup.sh, keep the AIM cleanup workaround there until AIM fixes
uninstall behavior.
Safe workaround: keep only the newest eventId-* directory inside each AIM
package directory before launching Batty sessions.
for package_dir in "${HOME}"/.aim/packages/*; do
[ -d "${package_dir}" ] || continue
newest=""
newest_mtime=0
for event_dir in "${package_dir}"/eventId-*; do
[ -d "${event_dir}" ] || continue
mtime="$(stat -c '%Y' "${event_dir}" 2>/dev/null || stat -f '%m' "${event_dir}")"
if [ "${mtime}" -gt "${newest_mtime}" ]; then
newest="${event_dir}"
newest_mtime="${mtime}"
fi
done
for event_dir in "${package_dir}"/eventId-*; do
[ -d "${event_dir}" ] || continue
[ "${event_dir}" = "${newest}" ] || rm -rf -- "${event_dir}"
done
done
Run that in the DevSpace startup hook before AIM package discovery. If a public
upstream AIM issue or PR becomes available, add its link to planning/issues.md
and keep this workaround until the soft-delete behavior is fixed.
MCP servers collide between concurrent engineers¶
Cause: Some MCP servers use fixed ports, socket paths, cache files, or remote lock/table keys. If two Batty engineers launch the same server with those singleton resources, one can fail silently or corrupt shared state.
Batty exports a per-member MCP namespace into every launched agent process:
printf '%s\n' "$BATTY_MCP_NAMESPACE"
printf '%s\n' "$BATTY_MCP_RESOURCE_DIR"
printf '%s\n' "$BATTY_MCP_PORT_BASE"
Configure MCP servers to derive resources from those variables:
--state-dir "$BATTY_MCP_RESOURCE_DIR/server-name"
--socket "$BATTY_MCP_RESOURCE_DIR/server-name.sock"
--port "$BATTY_MCP_PORT_BASE"
--ddb-prefix "$BATTY_MCP_NAMESPACE"
If a server cannot be namespaced, serialize it with the shared Batty lock:
flock "$BATTY_MCP_SHARED_LOCK" mcp-server-command
Two concurrent engineers should report different namespace/resource/port values and the same shared lock path. If not, restart the Batty daemon with a current binary and confirm the agent was launched by Batty rather than by hand.
No session to attach to¶
Cause: The team session isn't running.
tmux list-sessions # see what's running
batty start # start a new session
batty attach # then attach
Messages not being delivered¶
Cause: The daemon may not be running, or the target member name is wrong.
- Check daemon is alive:
cat .batty/daemon.pid # get PID
ps aux | grep batty # verify process is running
- Check the inbox directly:
batty inbox <member> # list all messages
- Check daemon logs:
tail -50 .batty/daemon.log
Agent not responding in its pane¶
Cause: The agent may have exited or be waiting for input.
- Attach and check:
batty attach, then navigate to the agent's pane - Check daemon logs for spawn errors:
tail .batty/daemon.log - Verify the agent binary is available:
which claudeorwhich codex
For unattended teams, keep auto_respawn_on_crash: true in team.yaml so
crashed shim agents are restarted automatically. Set it to false only while
debugging or when you want to restart panes manually.
batty send rejected: not allowed to message¶
Cause: The talks_to rules in team.yaml don't allow this communication path.
Check team.yaml and adjust talks_to for the sender's role. The default hierarchy is:
- Architect \<-> Manager
- Manager \<-> Engineer
The human (CLI user) can always message any role.
Validate fails: layout zones exceed 100%¶
Cause: Zone width_pct values in layout.zones sum to more than 100.
batty validate # shows the specific error
Adjust width_pct values to sum to 100 or less.
Worktree merge conflicts¶
Cause: An engineer's worktree branch conflicts with main.
batty merge eng-1-1 # attempt merge
If conflicts occur, resolve them manually in the worktree directory, then complete the merge.
Auto-merge outcomes differ between tasks¶
Cause: This is expected. Batty's auto-merge path has multiple supported
outcomes per task, so a batch of green completions can split across done,
review, retry, revert, or escalation.
Start with:
batty board summary
batty inbox manager
batty metrics
Then interpret the result per task:
- If the task moved to
review, Batty decided the diff was not safe for unattended merge. Common reasons are large diffs, config changes, migration changes, or an explicit per-task override. - If the engineer was told to retry after a rebase conflict, resolve the conflict in the engineer worktree and let them complete the task again.
- If the manager received a "failed post-merge verification on main and was
reverted" message, treat that as a real rollback. Inspect the failing output,
create follow-up work, and do not assume the change is still on
main. - If the manager received "passed tests but could not be merged to main", the queue could not finish the merge safely. Clean the main worktree if needed, retry manually, or redirect the engineer.
Telegram messages are not arriving¶
Cause: The bot token, allowed user ID, or Telegram chat bootstrap step is incomplete.
Check these in order:
- Confirm the
userrole in.batty/team_config/team.yamlhaschannel: telegramand achannel_configblock. - If you rely on
BATTY_TELEGRAM_BOT_TOKEN, verify it is exported in the shell that launchesbatty start. - DM the bot first and send
/start; Telegram will not let bots initiate a new chat. - Re-run
batty telegramif you need to refresh the token or allowed user ID. - Restart Batty after changes:
batty stop
batty start
Discord commands arrive but are ignored¶
Cause: The Discord bot can read channel metadata but cannot read message text because Message Content Intent is disabled.
Check batty status and .batty/daemon.log for a Discord MESSAGE_CONTENT intent fault. If present, open the Discord Developer Portal, select the bot
application, go to Bot -> Privileged Gateway Intents, enable Message Content
Intent, then restart Batty.
batty stop
batty start
Batty advances the Discord cursor even for empty-content messages so the same bad batch is not reprocessed forever; after enabling the intent, new content-bearing commands should be delivered normally.
Daemon dies unexpectedly¶
Cause: Check the daemon log for errors.
cat .batty/daemon.log
Common causes: tmux session was killed externally, agent binary not found, permission errors on inbox directories.
Restart with:
batty stop # clean up
batty start # fresh start
If Batty finds a stale saved session during startup, it falls back to a cold respawn with context rebuild instead of requiring a manual pane restart. Healthy live panes do not need a proactive restart; startup recovery only touches panes that are already dead.
Multiple orphaned batty sessions¶
Cause: Previous sessions from test runs or crashes.
batty stop # kills primary + all orphaned batty-* sessions