From 71f0e69578acef81916ba190d7b9df5c951c7861 Mon Sep 17 00:00:00 2001 From: Achieve Date: Fri, 27 Mar 2026 09:45:21 +0800 Subject: [PATCH] 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 --- Sources/TerminalController.swift | 44 +++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/Sources/TerminalController.swift b/Sources/TerminalController.swift index f1d6c377..66d1c723 100644 --- a/Sources/TerminalController.swift +++ b/Sources/TerminalController.swift @@ -5346,7 +5346,16 @@ class TerminalController { result = .err(code: "not_found", message: "Workspace not found", data: nil) 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 { result = .err(code: "not_found", message: "No focused surface", data: nil) return @@ -5397,7 +5406,16 @@ class TerminalController { result = .err(code: "not_found", message: "Workspace not found", data: nil) 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 { result = .err(code: "not_found", message: "No focused surface", data: nil) return @@ -5431,7 +5449,16 @@ class TerminalController { result = .err(code: "not_found", message: "Workspace not found", data: nil) 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 { result = .err(code: "not_found", message: "No focused surface", data: nil) return @@ -5482,7 +5509,16 @@ class TerminalController { 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 { result = .err(code: "not_found", message: "No focused surface", data: nil) return