Common Pitfalls and How to Avoid Them
High-frequency, battle-tested pitfalls from the community group, sorted by how often they occur and their impact.
Bot permissions / app creation (most common)
- Reusing a bot created from an old app / not using the latest
botmux setupQR-code creation / incomplete permissions: symptoms vary — the CLI looks like it "exits mid-session", the group receives no messages,botmux historyreturns 400, and so on; the root cause is usually incomplete bot permissions. → Use the latestbotmux setupto recreate the app by QR code (it auto-configures all permissions and publishes a version); don't reuse a bot created from an old app, and don't miss permissions when creating one manually.
Environment / Installation
- Node too old: v18 and similar lack a built-in global
fetch, sobotmux setupthrowsfetch is not defined/fetch failedand won't writebots.json. → Upgrade to Node ≥ 22. - First launch stuck on a manual confirmation: On first run, a CLI (such as Claude Code) pops up a "trust this directory / bypass permissions" confirmation. If nobody has clicked through it, it hangs and reports a
tmux send-keyserror. → Confirm it manually once, and it won't appear again.
Lost environment variables (high frequency)
- bash users who put variables in
.bash_profiledon't get them: A new worker starts withbash -i, andbash -ionly reads.bashrc. → In.bashrc, runsource ~/.bash_profile, or just put the variables directly in.bashrc(zsh users use.zshrc). This is a common root cause ofAPI Error 403/ gateway token errors. - Claude refuses
--dangerously-skip-permissionsunder root: It reports "cannot be used with root/sudo privileges". →export IS_SANDBOX=1(zsh in.zshrc, bash in.bashrc; for PM2 / systemd / Docker scenarios, configure it in the corresponding startup environment). Newer versions already inject this automatically for the root scenario.
Custom wrapper / gateway integration
- The wrapper doesn't pass arguments through: When wrapping CLI startup with a gateway script, if
"$@"isn't passed through correctly, the CLI won't receive arguments like--session-id. → Runbotmux logs, find theSpawning fresh CLI:line, copy the full command, and reproduce it locally to pin down the issue. - The wrapper blacklists botmux's arguments: For example, blocking
--settingsor reportingunknown option '--images'will cause startup to fail and drop into a shell. → Run that spawn command manually in your local shell to locate the problem, then allow the relevant arguments through.
Input / Submission
- A multi-line message gets split into multiple submissions: Some TUIs (Codex / CoCo) treat the
\nand\tinside a multi-line prompt as Enter / autocomplete keys and submit line by line. → Newer versions have switched Codex input to bracketed paste to work around this (consistent with CoCo). When you write multi-linebotmux sendyourself, always use a heredoc too. - "Forgetting" to send messages to Lark after context compaction: CLIs without a persistent system prompt (CoCo / Codex / Gemini / OpenCode) only inject the routing instructions in the first message of a topic. Once the context is compacted, the routing block is lost and the model answers directly in the terminal instead of sending to Lark. → Newer versions re-inject the full routing block on every follow-up for these CLIs; using a stronger model also helps.
- Weak models / wrapped models don't call
botmux send: They easily forget to call it, or keep calling it repeatedly without stopping. → Use a SOTA model, or add stronger prompt constraints. botmux send --imageswith ≥ 6 images may silently fail: → Send ≤ 4 at a time, in batches.
Processes / Connections
- One Lark bot wired to two apps both competing for the long connection: Whichever grabs the websocket first owns it, which makes botmux work intermittently. → One bot should connect to only one long-connection app.
- After
tmux kill-session, the session gets brought back up: The daemon still considers it active. → Usebotmux delete. - Once
defaultWorkingDiris configured, every single message spins up a new session: This is a side effect of "skipping repository selection". → If you don't want it, remove that config. - Codex 0.131+ headless reports a desktop attach socket error:
features.appsis enabled by default and tries to connect to the desktop. → botmux already adds--disable appsto the Codex it launches to work around this. - Running
botmux restartinside botmux's own tmux pane: Runtime variables (TMUX/LARK_*/BOTMUX_*) get inherited and pollute the daemon, causing sporadic token / gateway errors. → Restart the daemon from a clean, non-tmux shell. /reporepository numbers drift: Adding a new repository to the list shifts the numbering. → Don't hard-code numbers in automation; use/repo <project-name>or specify a unique path.
Disk / Logs
tmux-server-*.logfilling up the disk: These are only produced when tmux is started withtmux -v/-vv, have no automatic rotation, and can grow to hundreds of GB over a long run. botmux itself never uses-v, so these files can be safely deleted without affecting botmux logs.
Collaboration
- Two bots @-mentioning each other in an infinite loop: Each message ending with "send to @the other bot" loops forever. → Usually one side stopping on its own resolves it; fundamentally this is chatty model behavior, so add constraints.
Dashboard / Security
- Don't post a token-bearing dashboard URL into a group (it's equivalent to publicly exposing a temporary access credential). For security-sensitive scenarios, bind the host to the local machine:
BOTMUX_DASHBOARD_HOST=127.0.0.1. The token is single-use; each run ofbotmux dashboardregenerates it and the old link becomes invalid immediately. - Dashboard won't open: First run
curl http://<host>:<port>/__health; a{"ok":true}response means the service is healthy. The problem is usually a browser proxy / wrong host (a Mac's intranet IP can change) / opening a link with an old token.
General troubleshooting approach
For any "won't start locally / behaving abnormally" issue, follow these three steps first:
- Run
botmux logs, find theSpawning fresh CLI:line, copy the full command, and run it manually in your local shell to reproduce it (the fastest way to pin down permission / argument / login-state issues). - Open the Web Terminal to see the model's / gateway's real error at a glance.
- Hand the symptom to the local agent and let it self-diagnose; the community welcomes PRs.