Repository navigation
Non-PTY interactive build spins indefinitely and WSL process tree survives editor restart #5224
Description
Describe the bug
A Copilot SDK session in VS Code launched an OpenWrt prerequisite check through a non-PTY shell into WSL. With no build configuration, the build system invoked its interactive configuration menu implicitly. The menu process ran continuously on one CPU for approximately 10.5 hours with no further log output, while the chat continued to show background work.
The process tree was later found orphaned inside WSL after the editor had been restarted. This is a report about detecting and recovering from non-interactive background work, not a request to terminate intentionally detached services.
Affected version and environment
- Windows x64, VS Code, Copilot SDK agent session, WSL Ubuntu 22.04.
- The installed VS Code version at reporting time is 1.143.0. The exact editor and bundled runtime versions at the start of the incident were not captured.
- The standalone
copilot --versionshim cannot find a standalone CLI installation. This does not identify the version of the runtime bundled with VS Code. - This was not the built-in Agent mode's interactive terminal tool.
Observed sequence
-
A fresh OpenWrt v24.10.8 source tree had no
.config. -
The agent ran the equivalent of the following command in a non-interactive WSL process. Paths below are placeholders, not original local paths:
cd /tmp/repro make prereq > /tmp/repro-prereq.log 2>&1
-
The observed process chain was:
sh make prereq make V=s menuconfig sh -c .../mconf ... scripts/config/mconf -
OpenWrt's configuration prerequisite fell back to
make menuconfigbecause.configwas absent and the default configuration could not be copied. Consequently the requested prerequisite checks had not actually started. -
The
mconfprocess's stdin was a pipe, not a TTY. It remained runnable, accumulated approximately 10.5 CPU hours, and produced no further log output after the initial menu output. -
A later inspection found the outer shell's parent was WSL's
/init; the editor had been restarted, but the Linux process tree remained. -
Sending TERM to the individually verified processes stopped them. There was no compiler output, package output, or successful prerequisite result to recover.
After the diagnosis was supplied to the agent, it launched an equivalent unconfigured make prereq command again, producing the same mconf chain and several more minutes of CPU activity. That repetition is an agent execution/reasoning failure; it is not evidence of a particular runtime lifecycle bug.
Reproduction guidance
The sequence above is the observed reproduction, not a newly verified reproduction on the latest runtime.
To investigate independently, use only a disposable checkout of public OpenWrt v24.10.8 sources, without a .config, and invoke the prerequisite target through a non-PTY SDK shell. A source checkout alone is not sufficient: build-host dependencies must be present so that execution can reach mconf.
Do not repeat the unbounded command above. On a Linux host with GNU timeout, bound the experiment, for example:
cd /tmp/repro
timeout --kill-after=2s 30s make prereq </dev/null > /tmp/repro-prereq.log 2>&1This EOF-input variant is a proposed diagnostic, not a claim that its stdin conditions exactly match the original runtime's open pipe. If the timeout expires before mconf starts, that does not reproduce the incident.
For lifecycle investigation, record the task's execution mode, attachment mode, task ID and process tree before using the host's task-specific termination action. Verify termination of the descendants in WSL, not just the Windows launcher or the chat spinner. If testing editor restart, preserve the hard timeout.
Expected behavior
- Non-PTY execution should clearly explain that an interactive menu cannot be completed through that execution channel.
- A long-running task should expose enough state to distinguish an active build from a terminal-dependent process that is not making progress. Lack of output alone is not proof of a hang.
- A task-specific stop operation should provide a verifiable result for the task and its owned subprocesses, including subprocesses across the Windows/WSL boundary.
- The host should document what happens to attached work when the editor/session disconnects and how to find and stop surviving work after reconnecting. Intentionally detached work should remain distinct.
- A command deadline should be distinct from the initial wait before a synchronous shell is reported as background work.
Limits of the diagnosis
- I cannot establish from the available record whether the host successfully invoked task cancellation before the restart.
- The original shell's attachment mode was not captured. I am not claiming that an explicitly detached task violated its documented lifetime.
mconfconsuming CPU is established; the exact ncurses input-loop mechanism has not been instrumented.- This is not evidence of continuous model inference or a quantified token charge during those hours.
- I have not reproduced this on the latest Insiders build.
- Public SDK wrappers and VS Code integration code do not by themselves establish the root cause of runtime process ownership or WSL descendant cleanup. Please route this to the runtime or host owner as appropriate.
The application-level mitigation is to initialize and verify the build configuration non-interactively before running prerequisites, with an explicit deadline. Merely redirecting output or changing a shell's initial wait does not solve the interactive fallback.
Related reports
- docs: explain non-PTY command hangs and safe recovery copilot-sdk#2859: companion documentation mitigation for non-PTY execution and recovery; not a runtime cancellation fix.
- Agent Mode: Missing "Show and Focus Terminal" button and inability to interrupt (Ctrl+C) running commands due to isPty: false microsoft/vscode#341333: non-PTY commands cannot receive terminal Ctrl+C; the maintainer points to background-task termination instead.
- Copilot CLI (Copilot SDK) agent sessions can't use visible VS Code terminals, so the user can't complete interactive auth (SSH/sudo passwords) microsoft/vscode#341462: interactive terminal access in Copilot SDK sessions.
- No way to cancel/kill a dispatched background agent — a stuck one runs indefinitely and silently burns spend copilot-sdk#2822: cancellation of background agents, a different lifetime from the shell process reported here.
All paths are generic. No private project sources, firmware, device identifiers, screenshots, session IDs, raw logs, or original local directories are included.
Activity