fix(socket): return not_found error when surface_id is provided but unresolvable (#2150)

Previously, v2SurfaceSendText, v2SurfaceSendKey, v2SurfaceClearHistory, and
v2SurfaceReadText would silently fall back to ws.focusedPanelId when a caller
supplied a surface_id that could not be resolved (e.g. a stale ref or an ordinal
whose mapping had not yet been registered). This caused two distinct bugs:

- #2042: Commands like `cmux send --surface surface:9999` would succeed (exit 0)
  and deliver input to the focused pane instead of returning an error, making
  automation that targets specific surfaces unreliable.

- #2045: When the fallback landed on a browser panel, the subsequent
  ws.terminalPanel(for:) check failed and returned "Surface is not a terminal",
  making valid terminal surfaces appear broken when addressed by ref.

The fix adds an explicit check: if params["surface_id"] is present but
v2UUID() returns nil (resolution failure), we immediately return a not_found
error instead of falling back to the focused pane. When surface_id is absent,
the existing focused-pane fallback is preserved for backward compatibility.

Fixes #2042, Fixes #2045

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Achieve 2026-03-27 09:45:21 +08:00 committed by GitHub
parent f3c797ee44
commit 71f0e69578
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5346,7 +5346,16 @@ class TerminalController {
result = .err(code: "not_found", message: "Workspace not found", data: nil) result = .err(code: "not_found", message: "Workspace not found", data: nil)
return return
} }
let surfaceId = v2UUID(params, "surface_id") ?? ws.focusedPanelId let surfaceId: UUID?
if params["surface_id"] != nil {
surfaceId = v2UUID(params, "surface_id")
guard surfaceId != nil else {
result = .err(code: "not_found", message: "Surface not found for the given surface_id", data: nil)
return
}
} else {
surfaceId = ws.focusedPanelId
}
guard let surfaceId else { guard let surfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil) result = .err(code: "not_found", message: "No focused surface", data: nil)
return return
@ -5397,7 +5406,16 @@ class TerminalController {
result = .err(code: "not_found", message: "Workspace not found", data: nil) result = .err(code: "not_found", message: "Workspace not found", data: nil)
return return
} }
let surfaceId = v2UUID(params, "surface_id") ?? ws.focusedPanelId let surfaceId: UUID?
if params["surface_id"] != nil {
surfaceId = v2UUID(params, "surface_id")
guard surfaceId != nil else {
result = .err(code: "not_found", message: "Surface not found for the given surface_id", data: nil)
return
}
} else {
surfaceId = ws.focusedPanelId
}
guard let surfaceId else { guard let surfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil) result = .err(code: "not_found", message: "No focused surface", data: nil)
return return
@ -5431,7 +5449,16 @@ class TerminalController {
result = .err(code: "not_found", message: "Workspace not found", data: nil) result = .err(code: "not_found", message: "Workspace not found", data: nil)
return return
} }
let surfaceId = v2UUID(params, "surface_id") ?? ws.focusedPanelId let surfaceId: UUID?
if params["surface_id"] != nil {
surfaceId = v2UUID(params, "surface_id")
guard surfaceId != nil else {
result = .err(code: "not_found", message: "Surface not found for the given surface_id", data: nil)
return
}
} else {
surfaceId = ws.focusedPanelId
}
guard let surfaceId else { guard let surfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil) result = .err(code: "not_found", message: "No focused surface", data: nil)
return return
@ -5482,7 +5509,16 @@ class TerminalController {
return return
} }
let surfaceId = v2UUID(params, "surface_id") ?? ws.focusedPanelId let surfaceId: UUID?
if params["surface_id"] != nil {
surfaceId = v2UUID(params, "surface_id")
guard surfaceId != nil else {
result = .err(code: "not_found", message: "Surface not found for the given surface_id", data: nil)
return
}
} else {
surfaceId = ws.focusedPanelId
}
guard let surfaceId else { guard let surfaceId else {
result = .err(code: "not_found", message: "No focused surface", data: nil) result = .err(code: "not_found", message: "No focused surface", data: nil)
return return