fix: guard pane_title with ':' prefix — empty titles collapse TSV fields and corrupt restored cwd - #583
fix: guard pane_title with ':' prefix — empty titles collapse TSV fields and corrupt restored cwd#583josh-stephens wants to merge 1 commit into
Conversation
dump_panes() and the restore-side reader both parse the tab-delimited
pane line with 'IFS=$d read'. Tab is IFS-whitespace, so an EMPTY
pane_title field is collapsed and every subsequent field shifts left:
the dir lands in the title slot and pane_active lands in the dir slot.
Restore then reads a bogus dir ('1') and silently falls back to the
default cwd for every pane without a title, and paints ':/path' strings
onto pane titles.
window_format already guards window_name with the ':' prefix for
exactly this reason; pane_title (added in 1ad109d) missed the same
guard. Emit ':#{pane_title}' and strip the first char where the title
is applied on restore, matching the window_name/dir convention.
|
Confirming this from a real reboot, and adding one consequence I have not seen mentioned in the other reports of this bug (#520, #564, #581): the shift also swallows Env: tmux 3.4, tmux-resurrect at The mechanism
$ printf 'pane\tsess\t1\t0\t:\t0\t\t:/home/user/dotfiles\t0\tzsh\t2196\t500\n' |
while IFS=$'\t' read lt s w wa wf pi pane_title dir pane_active pane_command pane_pid hs; do
echo "pane_title=[$pane_title] dir=[$dir] pane_active=[$pane_active] pane_command=[$pane_command]"
done
pane_title=[:/home/user/dotfiles] dir=[0] pane_active=[zsh] pane_command=[2196]
What that looks like in a real save fileThis is the last autosave before the machine rebooted. Two shapes coexist in one file — panes with a title parse correctly, panes without one are shifted a column to the left: The third line is the interesting one. Why empty titles are common nowDefault After applying the changeI ran this with the Feeding those lines back through Two notes on the diff itselfThe One migration wrinkle worth a line in the PR body: save files written before the patch store the title without the guard, so the first restore after upgrading will strip the leading character from a non-empty title. It is cosmetic, it self-corrects on the next save, and titles are usually overwritten by the running program anyway — but it will surprise someone who restores from an old file and sees Happy to test any revision of this against my setup. |
The bug
dump_panes()(save.sh) and the pane-restore reader (restore.sh:178) both parse the tab-delimited pane record withwhile IFS=$d read …. Because tab is IFS-whitespace, bash collapses consecutive tabs, so a pane with an empty#{pane_title}loses that field entirely and every subsequent field shifts left by one::#{pane_current_path}lands in the title slot#{pane_active}(0/1) lands in the dir slotOn restore, the dir parses as
1→cdfails → the pane silently opens in the default cwd, and the path-string gets applied as the pane title (select-pane -T ':/home/user/project').Any pane whose title is empty is affected on every save. Panes whose programs set a title (e.g. via OSC 2) escape, which makes the corruption look random. On a 91-pane server this silently mis-restored ~75 panes' working directories.
The fix
window_format()already guards:#{window_name}for exactly this reason;pane_title(added in 1ad109d) just missed the same guard. This PR emits:#{pane_title}and strips the first char where the title is applied on restore — identical to the existing window_name/dir convention. Two-line change, no format-version bump needed beyond the same convention already in the file.🤖 Generated with Claude Code