Hi Antigravity team,
We identified an architectural deadlock scenario where a background task launched via run_command can permanently freeze the agent conversation loop.
Core Issue
When a CLI child process transitions to the background (after WaitMsBeforeAsync expires) and subsequently blocks on stdin (for instance, native Windows ssh.exe without -n or subshell quote stripping), the output log stays at 0 bytes.
Because system instructions strictly mandate reactive wakeup (“Do NOT poll or loop on status… The system will automatically notify you”), and the task runner currently lacks:
- Automatic
stdin detachment for non-interactive background tasks
- A default task execution timeout / watchdog
- Stall detection for extended 0-byte output
The agent loop never receives a wakeup event, causing the conversation to freeze indefinitely until manual intervention (>27 hours observed in production).
Full Report & Reproduction Steps
A detailed report with logs, process trees, and suggested mitigations has been submitted on GitHub:
[Bug] Background tasks via run_command freeze conversation permanently when child process blocks on stdin (lack of watchdog / timeout) · Issue #1121 · google-antigravity/antigravity-cli · GitHub
Hoping to see a task-level watchdog or default stdin null-routing in upcoming releases!
Hi @GeraldHuang0203,
Could you please share a few details:
- The Antigravity Version you are using?
- The Operating System you are using?
- If possible, can you please share the reproduction steps
Hi @GeraldHuang0203 and @Ambati_Rajendra,
A screen recording here will literally show 27 hours of a static cursor. The agent has not crashed; it is executing its system prompt contract with flawless obedience.
This is a textbook protocol-level deadlock between the CLI task supervisor and the agent instruction model. Having inspected the issue telemetry from GitHub Issue #1121 and reproduced the process lifecycle on Windows 11, the anatomy of the freeze is straightforward:
The Anatomy of the Deadlock
-
The System Prompt Mandate:
The agent’s native system prompt explicitly forbids polling:
“IMPORTANT: Do NOT poll or loop on status to wait for completion. The system will automatically notify you with a message when the command finishes. Simply proceed with other work or stop calling tools after launching a command.”
The agent is strictly conditioned to yield turns and await an asynchronous push event via the messaging harness.
-
The Supervisor stdin Inheritance:
When run_command exceeds WaitMsBeforeAsync (e.g. 5,000 ms), the CLI hands the execution to the background runner. However, the spawned subshell process maintains an open standard input handle. When a utility like native Windows ssh.exe (or an interactive PowerShell sub-prompt triggered by quote escaping) expects input, it blocks indefinitely waiting on stdin.
-
The Silent Loop:
Because stdin never receives an EOF or byte input, the child process emits 0 bytes of output and never terminates. Because the child never terminates, the supervisor never emits a reactive task completion event. And because the agent is ordered never to poll, the entire conversation remains locked forever.
(A related failure mode noted by @shleder on GitHub occurs when background stdout/stderr pipes lack active, non-blocking drain loops, saturating the 64 KB kernel buffer and deadlocking the child process on write operations).
Recommended Engineering Fixes for the Antigravity Team
- Automatic stdin Detachment on Background Handoff:
For non-daemon background tasks, the task supervisor must automatically disconnect or redirect stdin to NUL (Windows) or /dev/null (POSIX) immediately upon asynchronous transition, unless explicitly marked as interactive.
- Supervisor Watchdog & Zero-Byte Telemetry Gate:
The supervisor should enforce a default timeout or a zero-byte activity watchdog (e.g. if a non-daemon task produces 0 bytes of I/O for 10-15 minutes). Rather than leaving the socket dormant, inject an actionable synthetic notification back into the agent context (TaskStalledError: Child process waiting on input or inactive).
- Asynchronous Pipe Draining:
Ensure all background stdout/stderr descriptors are drained asynchronously to avoid kernel pipe saturation.
Immediate Client-Side Workaround for Developers
For anyone running commands that delegate to the background on Windows:
-
Remote SSH: Always enforce stdin redirection with the -n flag:
ssh -n user@host "command"
-
Script Isolation: Avoid multi-nested quotes in inline command strings; write execution logic to a temporary script file on disk and execute the script directly.
-
Agent-Side Watchdog via Schedule: If launching an asynchronous task prone to hanging, pair it with a conditional one-shot timer to guarantee a wake-up call:
schedule(DurationSeconds=600, TimerCondition="<task_id>", Prompt="Check if background task has stalled")
Gerald has documented the telemetry thoroughly in Issue #1121. Hopefully the CLI team can patch the stdio handle inheritance in the next release.