Description
Description
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] HEADCreate 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
/tmpand 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-execdoes 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
#31964reports changed-cwd session state and permission routing problems
through ACP.#35870reports 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.
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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊