My terminal thinks Claude Code is named '2.1.121'
I open-sourced my WezTerm config today. Most of it is unremarkable — Hebrew BiDi, a Ghostty-stolen palette, powerline tabs, a custom status bar with battery, load, RAM and a clock face that rotates with the time of day. The repo is at github.com/levz0r/dotfiles.
What was remarkable is what it took to make the tab titles legible.
The bug
My tab title function looked like this:
local proc = basename(pane.foreground_process_name)
local label = (cwd_name and (cwd_name .. ' · ' .. proc)) or proc
Reasonable. Each tab shows <dir> · <process>, e.g. dira · nvim, apeiros · psql. Worked for nvim, node, psql, ssh, every shell.
Then I opened a few Claude Code tabs and the tab strip filled with this:
1 apeiros · 2.1.121 2 data · 2.1.121 6 buildbench · 2.1.121
My first guess: pane title leak. Claude must be setting OSC 0;<title> to its version, and somewhere I’m falling back to pane.title. I’d just removed that fallback, so I went hunting.
No leak. The 2.1.121 was actually coming from pane.foreground_process_name. Claude Code renames its own process to its version number.
Why
I haven’t dug into the source, but a process can change its argv[0] (or use prctl(PR_SET_NAME) on Linux / setproctitle on macOS) to anything it wants. ps, top, and any tool that introspects the process table will see the new name. WezTerm’s foreground_process_name reads from there, so it sees 2.1.121 and dutifully reports it.
My guess at intent: it makes ps aux | grep claude useless, but ps aux | grep 2.1.121 immediately tells you which version you’re running. Convenient for the Claude team. Hostile to my tab bar.
The fix
Detect Claude two ways: by title (Claude Code substring) and by a process name that looks like a semver triple.
local function tab_proc(pane)
local detected = detect_from_title(pane.title)
if detected then return detected end
local p = basename(pane.foreground_process_name)
if p and p:match '^v?[%d]+%.[%d]+%.[%d]+' then return 'claude' end
return (p and #p > 0) and p or nil
end
Any process whose name starts with 1.2.3 is now treated as Claude. Then the Claude branch strips both the Claude Code prefix and the trailing · 2.1.121 from the title, leaving just the session name (or the cwd if there isn’t one).
Result:
1 🤖 dira 2 🤖 buildbench 3 🤖 Explore exotic themes…
The lesson
When you’re parsing data the OS gave you about another process, the other process gets to lie. foreground_process_name is not a name — it’s a string the program chose to expose. The same trick is why htop can show node servers as their npm script name and PostgreSQL as its current query.
I knew this in theory. I had to be reminded by a tab bar that read apeiros · 2.1.121.
The fix is six lines. The hour I spent staring at it was worth more than the lines themselves — that’s the kind of bug that earns a place in muscle memory.