Skip to content

OpenCode hangs after detached child-process tool call #33363

Closed as not planned
Closed as not planned

Description

@N0zoM1z0

Description

When OpenCode receives a shell tool call that starts a detached child process, the CLI does not return control within the bounded run.

The standalone reproducer installs public [email protected], starts a local mock provider, sends a shell command that spawns a detached sleep child and records its PID, and verifies that OpenCode reaches the provider and records the side effect but exits only by timeout/signal.

Plugins

None.

OpenCode version

1.17.9

Steps to reproduce

Prerequisites: Docker, Python 3, and the GitHub CLI (gh) for the clone command below. The linked reproducer is self-contained and uses only Python standard-library modules plus Docker. It installs the affected OpenCode version from the public npm package, starts a local mock provider, and runs the CLI in an isolated workspace. The Docker run is limited to 2 CPUs and 4 GiB RAM by default.

Complete self-contained reproducer: https://gist.github.com/N0zoM1z0/81da0b4f60e0c8d60533fac1cf15d629

The Gist contains opencode-child-process-cleanup.reproduce.py. Download and run:

gh gist clone 81da0b4f60e0c8d60533fac1cf15d629 opencode-child-process-cleanup-reproducer
cd opencode-child-process-cleanup-reproducer
python3 opencode-child-process-cleanup.reproduce.py

To reuse an already-built local image:

python3 opencode-child-process-cleanup.reproduce.py --skip-build

Expected successful reproduction output includes:

provider_requests_at_least: observed=... expected>=1
side_effect_file_exists detached-child.pid: bytes=... expected>=1
timeout_or_signal: returncode=137 timed_out=True
REPRODUCED

Actual behavior: OpenCode accepts the child-spawning shell tool call, records the detached-child PID side effect, and then fails to finish normally before the bounded timeout.

Expected behavior: OpenCode should track tool-started child processes and return control without hanging after the tool call completes or is boundedly failed.

Screenshot and/or share link

Not applicable. The linked reproducer prints the provider transcript checks and REPRODUCED.

Operating System

Linux x86_64 Docker, using a node:24-bookworm-based target image.

Terminal

Non-interactive CLI run from Python subprocess.

Activity

  1. github-actions commented on Jun 22, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is distinct from these (e.g., a different code path or reproducer), please clarify how it differs from #20902 in particular.

  2. N0zoM1z0 commented on Jun 25, 2026

    @N0zoM1z0
    Author

    Thanks for the duplicate/related-issue check. This may share the same root cause as #20902/#24731/#29294.

    The distinction I intended to capture is that this standalone reproducer runs against the current public package, [email protected], and shows the detached child-process cleanup/hang behavior still reproducing there with a deterministic local mock provider. If the current behavior is expected to be covered by the same shell-spawner/pipe-lifetime fix tracked in #20902, I am fine with consolidating this issue as a current-version reproduction of that root cause.

  3. github-actions commented on Aug 25, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

  4. trackoor commented on Aug 26, 2026

    @trackoor

    This remains reproducible. The previous closure was an automated inactivity closure, not a resolution or a determination that the report was invalid. The detached child-process cleanup/hang behavior described in the original report and reproducer remains applicable, so this issue should be reopened.

  5. N0zoM1z0 commented on Aug 26, 2026

    @N0zoM1z0
    Author

    Hi, I re-ran the original Gist reproducer against the current public npm latest package today, and this still reproduces for me.

    Reproducer used:
    https://gist.github.com/N0zoM1z0/81da0b4f60e0c8d60533fac1cf15d629

    Environment/version checks:

    • npm latest: [email protected]
    • Docker image built for this check: vendor-repro-opencode:1.18.23
    • Inside the container, opencode --version prints 1.18.23
    • I also checked the current npm dev tag, [email protected]

    Stable latest results with the original Gist reproducer, run 3 times:

    • Run 1: provider_requests=2, side_effect_file_exists detached-child.pid: bytes=2 expected>=1, timeout_or_signal: returncode=137 timed_out=True
    • Run 2: provider_requests=2, side_effect_file_exists detached-child.pid: bytes=2 expected>=1, timeout_or_signal: returncode=137 timed_out=True
    • Run 3: provider_requests=2, side_effect_file_exists detached-child.pid: bytes=2 expected>=1, timeout_or_signal: returncode=137 timed_out=True

    The current npm dev tag also reproduced:

    • provider_requests=2, side_effect_file_exists detached-child.pid: bytes=2 expected>=1, timeout_or_signal: returncode=137 timed_out=True

    I also ran a small control check with the same [email protected] Docker image and a simple Anthropic-compatible text-only response. That control exited normally with exit=0, timed_out=false, and provider_requests=2, so the timeout does not look like a generic Docker or mock-provider setup problem.

    Given that the detached child PID side effect is still observed and the CLI still does not return before the bounded timeout on latest stable and current dev tag, this still appears reproducible. If this is expected to be covered by the same root cause as the older detached/background process issues, could this be reopened or linked to the relevant tracking/fix issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions