Skip to content

Background detach rewriter appends duplicate & when command already ends with & #311470

@meganrogge

Description

@meganrogge

Bug

The POSIX branch of CommandLineBackgroundDetachRewriter unconditionally appends & to the command when chat.tools.terminal.detachBackgroundProcesses is enabled and a run_in_terminal call uses mode: "async" (legacy isBackground: true). If the model's command already ends with a single & (the background operator), the rewriter produces a trailing & &, which bash parses as "background the empty command after &" — either a silent no-op or a useless extra job.

Source: commandLineBackgroundDetachRewriter.ts

Observed in agent logs

Every time the agent's command already ends with & and mode: async is used, the rewriter appends another &:

  • pypi-server … &nohup pypi-server … & &
  • qemu-system-x86_64 … &nohup … & & (twice!)
  • cd /app && python3 service.py &nohup cd /app && python3 service.py & &
  • python3 -m http.server 8080 &nohup cd /var/www/git-deploy && python3 -m http.server 8080 & &

In 3 of 4 observed model-level retries the model noticed something was wrong, stripped the original &, and re-submitted with > /path 2>&1 & and mode: sync. That retry always worked — i.e. the agent was working around the rewriter bug.

Note the && case: the trailing & there is the background operator for the whole chain, not part of &&. The fix must distinguish & from &&.

Expected

If the incoming command already ends with a lone trailing & (ignoring trailing whitespace, and not &&), the rewriter should not append another &. It should still prefix with nohup.

Example:

  • pypi-server ... &nohup pypi-server ... & (not nohup pypi-server ... & &)
  • cd /app && python3 service.py &nohup cd /app && python3 service.py &
  • python3 app.pynohup python3 app.py & (unchanged behavior)

Related minor issue

For forensics, it would be clearer if async commands also emitted a Finished event with an execute strategy result like idle-after-output, so terminal.log starts/ends can be paired without cross-referencing chat-export-logs.json to confirm the async command was handled correctly.

Fix

Handled in the POSIX branch of _rewriteForPosix by trimming trailing whitespace and checking for a lone trailing & before appending.

Metadata

Metadata

Assignees

Labels

bugIssue identified by VS Code Team member as probable bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions