Skip to content

Conversation

@ethanndickson
Copy link
Member

@ethanndickson ethanndickson commented Dec 10, 2025

Problem

Background processes are stored in a Map<processId, BackgroundProcess> in BackgroundProcessManager. The processId was set directly from displayName, and it's also used to compute the output directory:

const processId = config.displayName;
// ...
const outputDir = `${bgOutputDir}/${workspaceId}/${processId}`;

When a new process is spawned in the background with a display name that was previously used:

  1. It gets the same outputDir as the old process
  2. The old exit_code file still exists in that directory (written by shell trap on exit)
  3. When refreshRunningStatuses() checks the new process, it reads the stale exit_code file
  4. The new process is immediately marked as "exited" even though it just started
  5. The banner filters to status === "running"process doesn't appear

Additionally, the map entry itself gets overwritten, losing tracking of any previous process with that name.

Fix

Append incrementing suffix (1), (2), etc. when a collision is detected:

let processId = config.displayName;
let suffix = 1;
while (this.processes.has(processId)) {
  processId = `${config.displayName} (${suffix})`;
  suffix++;
}

This ensures each process gets a unique outputDir, so no stale exit_code files interfere.

The original displayName is preserved separately on the BackgroundProcess object for UI display - the banner shows clean names like "Dev Server" while the agent receives unique IDs like "Dev Server (1)" to reference specific processes.

Generated with mux

Process IDs are used as Map keys in BackgroundProcessManager. Since
processId was set directly from displayName, spawning a new process
with a previously-used display name would overwrite the existing map
entry - even if the original process was still tracked (running or
exited).

Fix: append (1), (2), etc. when a processId collision is detected.
The original displayName is preserved separately for UI display.
@ethanndickson ethanndickson reopened this Dec 10, 2025
@ethanndickson ethanndickson added this pull request to the merge queue Dec 10, 2025
Merged via the queue into main with commit aaf26a8 Dec 10, 2025
36 checks passed
@ethanndickson ethanndickson deleted the background-processes-3ydc branch December 10, 2025 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant