Merge pull request #4047 from PeterPonyu/fix/3894-skip-tmux-layout-when-server-unreachable

fix(team-mode): skip tmux layout when opencode server unreachable
This commit is contained in:
YeonGyu-Kim
2026-05-15 20:25:22 +09:00
committed by GitHub
2 changed files with 31 additions and 1 deletions
+22
View File
@@ -175,6 +175,28 @@ describe("createManagers", () => {
expect(markServerRunningInProcess).toHaveBeenCalledTimes(1)
})
it("#given tmux is enabled but ctx.serverUrl is undefined #when managers are created #then it does NOT mark the server as running (issue #3894)", () => {
// Vanilla `opencode` (no `opencode serve` / `opencode web`) leaves
// ctx.serverUrl undefined. Marking the server as in-process running
// would short-circuit isServerRunning() in createTeamLayout, letting
// it spawn tmux panes whose `opencode attach` then fails because no
// server is actually listening on the fallback port.
const ctx = createContext("/tmp")
const ctxWithoutServerUrl = { ...ctx, serverUrl: undefined as unknown as URL }
const args = {
ctx: ctxWithoutServerUrl,
pluginConfig: OhMyOpenCodeConfigSchema.parse({}),
tmuxConfig: createTmuxConfig(true),
modelCacheState: createModelCacheState(),
backgroundNotificationHookEnabled: false,
deps: createDeps(),
}
createManagers(args)
expect(markServerRunningInProcess).not.toHaveBeenCalled()
})
it("#given openclaw is enabled #when the background session-created callback runs #then it dispatches openclaw with the tracked pane id", async () => {
const args = {
ctx: createContext("/tmp/project"),
+9 -1
View File
@@ -57,7 +57,15 @@ export function createManagers(args: {
const { ctx, pluginConfig, tmuxConfig, modelCacheState, backgroundNotificationHookEnabled } = args
const deps = { ...defaultCreateManagersDeps, ...args.deps }
if (tmuxConfig.enabled) {
// Only mark the server as in-process when the SDK actually exposes a
// serverUrl. `tmuxConfig.enabled` alone is not proof of a running server —
// a vanilla `opencode` session (no `opencode serve`/`opencode web`) leaves
// `ctx.serverUrl` undefined, and marking it running would make
// `isServerRunning` short-circuit to true. That bypasses the guard in
// `createTeamLayout` and lets it spawn tmux panes whose `opencode attach`
// command then fails because nothing is actually listening on the
// fallback port (issue #3894).
if (tmuxConfig.enabled && ctx.serverUrl) {
deps.markServerRunningInProcessFn()
}
const tmuxSessionManager = new deps.TmuxSessionManagerClass(ctx, tmuxConfig)