[Bug] tmux pane spawning fails in GitBash with tmux enabled
Status Closed — not planned
Reported on v2.1.34
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 14 comments · opened Feb 6, 2026 · closed Apr 14, 2026
Bug Description
can't swapn tmux pane running in GitBash with tmux enable
Environment Info
- Platform: win32
- Terminal: tmux + alacritty + windows 11
- Version: 2.1.34
- Feedback ID: 55b5668b-4554-444f-9e3c-619fad0790d5
Errors
[{"error":"Error: [TmuxBackend] Failed to get pane count for #session_name:#window_index (exit 1): can't find session: #session_name\n at getCurrentWindowPaneCount (B:/~BUN/root/claude.exe:2026:837)\n at async createTeammatePaneWithLeader (B:/~BUN/root/claude.exe:2029:496)\n at async createTeammatePaneInSwarmView (B:/~BUN/root/claude.exe:2025:16560)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:56:51.559Z"},{"error":"Error: Could not determine pane count for current window\n at createTeammatePaneWithLeader (B:/~BUN/root/claude.exe:2029:523)\n at async createTeammatePaneInSwarmView (B:/~BUN/root/claude.exe:2025:16560)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:56:51.560Z"},{"error":"Error: [TmuxBackend] Failed to get pane count for #session_name:#window_index (exit 1): can't find session: #session_name\n at getCurrentWindowPaneCount (B:/~BUN/root/claude.exe:2026:837)\n at async createTeammatePaneWithLeader (B:/~BUN/root/claude.exe:2029:496)\n at async createTeammatePaneInSwarmView (B:/~BUN/root/claude.exe:2025:16560)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:00.843Z"},{"error":"Error: Could not determine pane count for current window\n at createTeammatePaneWithLeader (B:/~BUN/root/claude.exe:2029:523)\n at async createTeammatePaneInSwarmView (B:/~BUN/root/claude.exe:2025:16560)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:00.843Z"},{"error":"Error: EPERM: operation not permitted, symlink 'C:\\Users\\nikiforovall\\.claude\\projects\\C--Users-nikiforovall-dev\\e8a039b3-3286-489a-a517-9b6e8c564da5\\subagents\\agent-a537b02.jsonl' -> 'C:\\Users\\NIKIFO~1\\AppData\\Local\\Temp\\claude\\C--Users-nikiforovall-dev\\tasks\\a537b02.output'\n at symlinkSync (unknown)\n at kFH (B:/~BUN/root/claude.exe:1316:1154)\n at kRD (B:/~BUN/root/claude.exe:1428:1523)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:972)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:1893)\n at run (node:async_hooks:62:22)\n at sPH (B:/~BUN/root/claude.exe:1173:94)\n at call (B:/~BUN/root/claude.exe:2043:667)\n at async cUE (B:/~BUN/root/claude.exe:3465:13995)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:07.972Z"},{"error":"Error: EPERM: operation not permitted, symlink 'C:\\Users\\nikiforovall\\.claude\\projects\\C--Users-nikiforovall-dev\\e8a039b3-3286-489a-a517-9b6e8c564da5\\subagents\\agent-ac6fe93.jsonl' -> 'C:\\Users\\NIKIFO~1\\AppData\\Local\\Temp\\claude\\C--Users-nikiforovall-dev\\tasks\\ac6fe93.output'\n at symlinkSync (unknown)\n at kFH (B:/~BUN/root/claude.exe:1316:1154)\n at kRD (B:/~BUN/root/claude.exe:1428:1523)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:972)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:1893)\n at run (node:async_hooks:62:22)\n at sPH (B:/~BUN/root/claude.exe:1173:94)\n at call (B:/~BUN/root/claude.exe:2043:667)\n at async cUE (B:/~BUN/root/claude.exe:3465:13995)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:10.760Z"},{"error":"Error: EPERM: operation not permitted, symlink 'C:\\Users\\nikiforovall\\.claude\\projects\\C--Users-nikiforovall-dev\\e8a039b3-3286-489a-a517-9b6e8c564da5\\subagents\\agent-aa3e5dd.jsonl' -> 'C:\\Users\\NIKIFO~1\\AppData\\Local\\Temp\\claude\\C--Users-nikiforovall-dev\\tasks\\aa3e5dd.output'\n at symlinkSync (unknown)\n at kFH (B:/~BUN/root/claude.exe:1316:1154)\n at kRD (B:/~BUN/root/claude.exe:1428:1523)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:972)\n at <anonymous> (B:/~BUN/root/claude.exe:2043:1893)\n at run (node:async_hooks:62:22)\n at sPH (B:/~BUN/root/claude.exe:1173:94)\n at call (B:/~BUN/root/claude.exe:2043:667)\n at async cUE (B:/~BUN/root/claude.exe:3465:13995)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:13.700Z"},{"error":"Error: Request was aborted.\n at XW$ (B:/~BUN/root/claude.exe:838:99554)\n at lnI (B:/~BUN/root/claude.exe:5693:4372)\n at nnI (B:/~BUN/root/claude.exe:5698:7410)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:32.437Z"},{"error":"Error: Request was aborted.\n at makeRequest (B:/~BUN/root/claude.exe:333:3940)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:32.439Z"},{"error":"Error: Request was aborted.\n at makeRequest (B:/~BUN/root/claude.exe:333:3940)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-06T12:57:32.440Z"},{"error":"Error: […
Note: Content was truncated.
14 Comments
<img width="1240" height="153" alt="Image" src="https://github.com/user-attachments/assets/cd2f3b93-1392-42fd-b6b6-a70740d849d0" />
Additional findings from investigation
Tried to work around the
#session_name:#window_indexissue by creating a tmux wrapper script that resolves format variables before passing to the real binary.What we tried:
~/bin/tmuxthat intercepts calls and resolves#session_name/#window_indexviatmux display-message -p '#{session_name}'~/bin/tmuxis found first in PATH (which -a tmuxconfirmed it)Result: The wrapper was never called — the log file remained empty. Claude Code's bundled binary (
claude.exe) appears to resolve tmux via absolute path (/usr/bin/tmux) internally, bypassing shell PATH entirely. This means alias/wrapper approaches cannot fix the issue — it needs to be fixed in Claude Code's tmux backend code.Environment: Windows 11, MINGW64/Git Bash, tmux 3.6a, Claude Code 2.1.34
Same problem here with windows 11/wezterm/tmux. Tried to ask claude to fix the issue but here is the answer:
I found the root cause. Look at this output from the compound tmux command:
session=#\{session_name\ window=#\{window_id\ panes=#\{window_panes\}The #{} tmux format strings are getting escaped by MSYS2's bash in certain invocation contexts. When Claude Code internally runs tmux display-message -p '#{window_panes}' to count panes, the #{} sequences get mangled instead of being interpreted by tmux, so it gets back garbage instead of a number — hence "Could not determine pane count".
This is a Claude Code platform bug on Windows/MSYS2 — the tmux format strings aren't being passed through correctly.
You can't fix it from your side.
Using Claude Code on Windows has been one of the most frustrating experiences lately. Sometimes, new features often don't work from the first try🙈
Same problem here with Windows 11/WindowsTerminal/tmux.
Case 1: Fails (format string at beginning)
Expected:
3Actual:
#window_panes(literal string)Case 2: Works (format string with prefix)
Result: Format string is expanded correctly
Case 3: Works (format string with text prefix)
Result: Format string is expanded correctly
Additional confirmation + diagnostic data
Confirming this on Claude Code 2.1.56 (latest). Tested across two different terminal emulators to rule out the terminal layer:
| Terminal Host | Emulator | tmux | Result |
|---------------|----------|------|--------|
| Windows Terminal | conpty | 3.6a | FAIL — "Could not determine pane count" |
| git-bash.exe | mintty | 3.6a | FAIL — same error |
Window size is irrelevant — tested maximized (209x50), normal (120x29), and fresh restarts. Same failure every time.
Extra diagnostic detail
The
#{...}format string escaping issue (identified by @Takeuch-Code) also explains why terminal size detection appears broken in Claude Code's subprocess:| Method | Result | Notes |
|--------|--------|-------|
|
tput cols/tput lines| 80 / 24 (default) | Falls back to default in subprocess ||
stty size| "Inappropriate ioctl for device" | No pty attached to subprocess ||
$COLUMNS/$LINES| empty | Not inherited ||
tmux display-message -p '#{client_width}x#{client_height}'| Correct (209x51) | Only works from bash, not when Claude Code invokes it internally |So even if Claude Code tried
tmux display-messageas a fallback, it would still hit the same#{...}escaping issue when invoking via MSYS2 bash.Additional observation: TMUX socket path
The
$TMUXvariable on MINGW64 uses a Windows-style drive letter:vs expected Unix-style
/tmp/tmux-1000/default. This may cause secondary parsing issues if the code splits on:or expects/as the first character.Environment
What works
TeamCreate,TeamDelete,TaskCreate, andTask(withoutteam_name) all succeed. Only teammate spawn withteam_namefails.This MSYS2
#{...}escaping issue is fundamentally unfixable in GitBash because the shell layer will always mangle tmux format strings. An alternative: psmux — a native Windows tmux implementation that eliminates the MSYS2 layer entirely.psmux maintainer here. The root cause here is well-identified: MSYS2's bash mangles
#{session_name},#{window_panes}, etc. when Claude Code invokes tmux internally. As @Takeuch-Code demonstrated:Why psmux avoids this
psmux is a native Windows binary (~4.5MB, Rust, ConPTY) — no MSYS2, no MinGW, no bash translation layer. When Claude Code calls
tmux display-message -p '#{window_panes}', the format strings go directly to the psmux process without any shell escaping in between.It also fixes @Josefvz's socket path issue. psmux sets:
This matches the Unix-style format that Claude Code's parser expects (splits on
:, expects/prefix) — unlike theC:/Users/.../tmux-4096/defaultpath from MSYS2 tmux.How to try it
Then run Claude Code from PowerShell or Windows Terminal (not GitBash). psmux ships as
tmux.exe, so Claude Code's tmux detection (which tmux,$TMUXenv var) works automatically.76 tmux-compatible commands, including all the ones Claude Code's TmuxBackend uses:
display-message,split-window,list-panes,send-keys,select-pane,resize-pane.Current release: v0.4.10 — MIT licensed.
The
tmux -Vcommand also works correctly (fixed in #42), which is how many tools detect tmux presence.@marlocarlo create project, thank you for sharing. If we talk about feature partiy. Will plugin system/customizations work for
psmux? I use alacritty and gitbashYes, technically, it should. I've not tested it with git bash ,only tried Powershell psmux plugins on psmux but I think it should work, perhaps tmux plugins as Psmux is compatible. Let me know if you face issues. I'll try to address it
Psmux can be made to load git bash as the shell when you run Psmux from powershell. I fixed some issues related to this in the latest commits and tested.That works. The plugin part inside gitbash,I am not sure.
@marlocarlo First off, thanks for the feedback!
I installed psmux and gave it a go. Two issues so far (though it's completely possible I'm doing something wrong.)
I have to launch
tmux(in Windows Terminal) before Claude, otherwise it doesn't pick tmux up at all.Claude does create additional instances (panes)! So progress!! However, it looks like the command being passed to the spawned tmux instances is broken; see the image below.
Let me know if I need to change something, or whether we should move this discussion to another issue (I'm not sure whether this is a psmux or Claude issue).
<img width="1909" height="1023" alt="Image" src="https://github.com/user-attachments/assets/8a90df9b-44aa-4412-a62a-59ba8818e8e0" />
@Josefvz Great catch — thank you for the detailed report and screenshot!
I've identified and fixed both issues. The commit is here: https://github.com/marlocarlo/psmux/commit/fde3adf
What was broken
1. The
-c(start directory) flag was silently ignoredWhen Claude Code runs
split-window -h -d -c <dir> -P -F "#{pane_id}", the-cargument was being parsed correctly but the value was discarded (_start_dir) before reaching the pane creation code. This means teammate panes always spawned in psmux's own working directory instead of the project directory Claude intended.Fixed:
start_diris now wired through the full call chain —app.rs,server/mod.rs,commands.rs,input.rs— so bothsplit-window -candnew-window -ccorrectly set the working directory of new panes.2.
build_command()sent/Cto bash instead of-cWhen psmux spawns a command in a pane, it needs to invoke the shell with the right flag. The code only detected PowerShell (
-Command) and defaulted everything else tocmd.exe /C. So if your default shell is bash, the commandbash /C "echo hello"would be sent — which bash doesn't understand.Fixed:
build_command()now does proper file-stem detection:pwsh/powershell→-Commandbash/sh/zsh/fish/dash/ash→-c/C(cmd.exe)How to update
Or if you have the repo cloned:
Verified with tests
I've added a comprehensive test suite (
tests/test_claude_compat_fixes.ps1) that covers the full Claude Code teammate workflow — 26 tests all passing:split-window -candnew-window -ccorrectly set CWDsplit-window -h -d -c <dir> -P -F "#{pane_id}"(exact Claude Code spawn pattern)-cinstead of/Csend-keysto split panesLet me know if this resolves it for you!
@NikiforovAll I can confirm that this now works on my side @psmux and the team that side has done some great work on psmux!
<img width="1898" height="1023" alt="Image" src="https://github.com/user-attachments/assets/9ef0264d-c040-4448-8677-49191977797a" />
Hopefully this solves your issue as well
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.