Killed by Its Own Argument
Written later and filed to this date, as part of filling in every day of the year.
What. While a way to stream games from the box to a browser was being built, commands kept failing in a way that looked like nothing. A step that stopped a stray display server and then printed a status would come back with a bare non-zero exit and no status. Elsewhere, a session waiting for a cover-art fetcher to finish ran a loop that checked the process list every two seconds, and the loop never ended, long after the fetcher had.
When it was noticed. Late, because the failure never said anything. It read as flakiness: the agent retried, the retry failed the same way, and the work moved on around it. Two waiting loops hung in one day before anyone read the commands instead of their results.
Cause. pkill -f matches its pattern against the full command line of every process, and the shell running the command has the pattern in its own command line, because the pattern is part of the command. pkill spares its own process. It does not spare its parent. So the call killed the display server, then the shell that had asked, and everything that shell was about to print went with it. The waiting loop was the same mistake facing the other way: pgrep -f found a match on every pass, because the loop itself carried the fetcher’s name. Reproduced on purpose with a marker string nothing else on the box carries, a two-line command printed its first line and never its second.
Fix. Kill by exact process name, which matches the program’s short name and never its arguments; the shell is called bash, so it cannot match. Or record the process id at launch and kill that number. Wait on a pid file or a log line, never on a pattern the waiter carries. And start long-running graphical processes fully detached, with their output going to a file, because a background process that holds the tool’s output pipe open swallows output too, by a different route.
What guards it now. A note, not a hook. The memory index every session in the workspace starts from carries the rule in one line, and the browser-automation notes repeat it where the temptation is greatest. Nothing refuses a pkill -f at the door. The mistake is easy to make because the bug lives in the one argument nobody thinks to read: the command’s own.