You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
opencode run --session --fork stalls with zero output when --dir changes to a Git worktree #46276
opencode run --session <id> --fork completes when the child keeps the parent
session's directory, but can stall before emitting its first JSON event when --dir changes to another Git worktree of the same repository.
The stalled process produces zero stdout and zero stderr until it is killed by
an external timeout. The reproduction is sequential: no two opencode run
processes overlap.
Environment
macOS 14.6.1 (23G93), Intel x86_64
Reproduced with OpenCode 1.17.11 and 1.18.25
opencode run --format json
Reproduced without a filesystem sandbox, permission overlay, or wrapper
Minimal reproduction
Start with a Git repository at [REPO_A] and create a second worktree:
git -C [REPO_A] worktree add --detach [REPO_B] HEAD
Create two equivalent one-turn parent sessions in [REPO_A], recording their
session IDs as [SAME_DIR_PARENT] and [CROSS_DIR_PARENT]. Use each parent only
once in the controls below.
Same-directory control — completes and emits step_start, text, and step_finish:
printf'%s\n''Reply exactly OK. Do not use tools.'|
opencode run --format json --dir [REPO_A] \
--session [SAME_DIR_PARENT] --fork --model [PROVIDER/MODEL]
Cross-directory case — stalls with zero stdout and stderr:
printf'%s\n''Reply exactly OK. Do not use tools.'|
opencode run --format json --dir [REPO_B] \
--session [CROSS_DIR_PARENT] --fork --model [PROVIDER/MODEL]
An external 25–30 second timeout is needed to terminate the second command.
Observed controls
Fresh sessions complete in both /tmp and the source Git repository.
A one-shot fork that keeps the parent directory completes.
A one-shot fork from an equivalent parent into a different worktree stalls
before its first event.
The cross-directory stall reproduces on both 1.17.11 and 1.18.25.
Adding or removing the caller's permission overlay does not change the result.
Adding or removing macOS sandbox-exec does not change the result.
Exporting/importing the parent with the worktree directory and resuming the
imported session also stalled in the observed environment.
Expected behavior
The fork should preserve the parent context and launch in the requested
directory, or fail quickly with an actionable error if changing the child
directory is unsupported. It should not remain alive indefinitely with no
stdout or stderr.
Related issues
#31964 reports changed-cwd session state and permission routing problems
through ACP.
#35870 reports intermittent headless startup hangs, especially for fresh
directories.
This reproduction is narrower: opencode run --session ... --fork, sequential
processes, same Git repository, and same-directory versus sibling-worktree
controls.
Independent human-guided terminal confirmation on a second controlled run:
Environment:
macOS 14.6.1 (23G93), Intel x86_64
OpenCode 1.17.11 at /usr/local/bin/opencode
Commands run sequentially
No CHATR-BUS process, permission overlay, or sandbox-exec
Two separate parent sessions, each forked exactly once
External Python subprocess timeout: 30 seconds
Results:
Fresh session started directly in detached worktree B: completed in 8.85 s,
exit 0, one step_start, one text event, one step_finish, zero stderr.
Fresh parent created in source directory A: completed in 10.28 s.
Parent A forked with child also in A: completed in 9.46 s, exit 0, complete
event sequence, and a distinct child session ID.
Separate equivalent parent created in A: completed in 8.07 s.
Parent A forked with child --dir changed to detached worktree B: timed out
after 30.09 s with zero stdout bytes, zero stderr bytes, no events, and no
child session ID.
The worktree was then removed cleanly and no test OpenCode process remained.
This supports the narrow same-directory-versus-cross-directory distinction in
the issue. The test does not determine OpenCode's internal cause.
Follow-up: the combined CLI hang still reproduces, but OpenCode 1.18.25's
experimental native workspace control plane provides a working alternative for
the underlying use case.
Validated sequence:
Start an OpenCode 1.18.25 server with OPENCODE_EXPERIMENTAL_WORKSPACES=true, scoped to source directory A.
Fork the parent through POST /session/:id/fork while still scoped to A.
Register/discover existing Git worktree B with POST /experimental/workspace/sync-list.
Warp only the child with POST /experimental/workspace/warp.
Prompt the child normally; its workspace ID routes execution to B.
Warp the child back with workspace ID null before workspace removal.
Results on OpenCode 1.18.25:
existing detached worktree discovered;
distinct child created, parent unchanged;
child inherited parent context;
child Bash pwd and own writes operated in B;
under an outer macOS seatbelt profile, writes to source A, another worktree, /tmp, TMPDIR, and cache paths were denied;
child detached and remained resumable afterward; and
workspace row and Git worktree removed cleanly.
This does not make the opencode run --session PARENT --fork --dir B stall
expected: that command should still complete or fail explicitly. It does narrow
the issue to the combined CLI path; OpenCode's native fork-then-warp workflow
works for the session-in-worktree use case.
This is a concrete blocker for me, not just an edge case.
The session’s stored working directory can become stale when the original directory is deleted, renamed, moved, or—as in my case—was a temporary directory created by the host application and no longer exists.
Once session.directory points to a non-existing path, I can no longer resume or fork that session, even if I explicitly provide a valid directory:
opencode run --session <session-id> --fork --dir <existing-directory>
OpenCode still tries to resolve the stale stored directory and fails before the requested --dir can take effect.
I verified that the session itself is otherwise intact: changing only its directory field in opencode.db to a valid path makes the same session resume successfully with its full history.
So there is currently no supported recovery path for this situation. The session is effectively blocked unless the database is edited manually.
An explicit --dir should either override the stale stored directory for the fork/resume, or OpenCode should provide another supported way to rebind the session to a valid directory.
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.
Activity
Great-Bucket commentedon Aug 30, 2026
Independent human-guided terminal confirmation on a second controlled run:
Environment:
/usr/local/bin/opencodesandbox-execsubprocesstimeout: 30 secondsResults:
exit 0, one
step_start, one text event, onestep_finish, zero stderr.event sequence, and a distinct child session ID.
--dirchanged to detached worktree B: timed outafter 30.09 s with zero stdout bytes, zero stderr bytes, no events, and no
child session ID.
The worktree was then removed cleanly and no test OpenCode process remained.
This supports the narrow same-directory-versus-cross-directory distinction in
the issue. The test does not determine OpenCode's internal cause.
Great-Bucket commentedon Aug 30, 2026
Follow-up: the combined CLI hang still reproduces, but OpenCode 1.18.25's
experimental native workspace control plane provides a working alternative for
the underlying use case.
Validated sequence:
OPENCODE_EXPERIMENTAL_WORKSPACES=true, scoped to source directory A.POST /session/:id/forkwhile still scoped to A.POST /experimental/workspace/sync-list.POST /experimental/workspace/warp.nullbefore workspace removal.Results on OpenCode 1.18.25:
pwdand own writes operated in B;/tmp, TMPDIR, and cache paths were denied;This does not make the
opencode run --session PARENT --fork --dir Bstallexpected: that command should still complete or fail explicitly. It does narrow
the issue to the combined CLI path; OpenCode's native fork-then-warp workflow
works for the session-in-worktree use case.
MartinSchlott commentedon Sep 19, 2026
This is a concrete blocker for me, not just an edge case.
The session’s stored working directory can become stale when the original directory is deleted, renamed, moved, or—as in my case—was a temporary directory created by the host application and no longer exists.
Once
session.directorypoints to a non-existing path, I can no longer resume or fork that session, even if I explicitly provide a valid directory:opencode run --session <session-id> --fork --dir <existing-directory>OpenCode still tries to resolve the stale stored directory and fails before the requested
--dircan take effect.I verified that the session itself is otherwise intact: changing only its
directoryfield inopencode.dbto a valid path makes the same session resume successfully with its full history.So there is currently no supported recovery path for this situation. The session is effectively blocked unless the database is edited manually.
An explicit
--dirshould either override the stale stored directory for the fork/resume, or OpenCode should provide another supported way to rebind the session to a valid directory.thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊