From b278e49e96cb2a7eb6700dfdee72ecedb8ca03f0 Mon Sep 17 00:00:00 2001 From: Simon Klee Date: Fri, 5 Jun 2026 11:45:03 +0200 Subject: [PATCH] tui: guard path formatting inputs (#30469) Fixes #27726, #25216, #24856, #24294, #17071, #29164, #24837, #16865, #14279, #29895 --- .../opencode/src/cli/cmd/tui/context/path-format.tsx | 2 +- .../src/cli/cmd/tui/routes/session/index.tsx | 4 ++-- .../src/cli/cmd/tui/routes/session/permission.tsx | 12 +++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/path-format.tsx b/packages/opencode/src/cli/cmd/tui/context/path-format.tsx index 1c9f19c6c..ba46a6292 100644 --- a/packages/opencode/src/cli/cmd/tui/context/path-format.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/path-format.tsx @@ -24,7 +24,7 @@ export function usePathFormatter() { } function formatPath(input: string | undefined, base: string | undefined) { - if (!input) return "" + if (typeof input !== "string" || !input) return "" const root = base || process.cwd() const absolute = path.isAbsolute(input) ? input : path.resolve(root, input) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 27ee66c7b..80fb10b8a 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -2534,7 +2534,7 @@ function Skill(props: ToolProps) { function Diagnostics(props: { diagnostics?: Record[]>; filePath: string }) { const { theme } = useTheme() const errors = createMemo(() => { - const normalized = Filesystem.normalizePath(props.filePath) + const normalized = Filesystem.normalizePath(typeof props.filePath === "string" ? props.filePath : "") const arr = props.diagnostics?.[normalized] ?? [] return arr.filter((x) => x.severity === 1).slice(0, 3) }) @@ -2564,7 +2564,7 @@ function input(input: Record, omit?: string[]): string { } function filetype(input?: string) { - if (!input) return "none" + if (typeof input !== "string" || !input) return "none" const ext = path.extname(input) const language = LANGUAGE_EXTENSIONS[ext] if (["typescriptreact", "javascriptreact", "javascript"].includes(language)) return "typescript" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx index 3191ed318..e199583a9 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx @@ -21,7 +21,7 @@ import { usePathFormatter } from "../../context/path-format" type PermissionStage = "permission" | "always" | "reject" function filetype(input?: string) { - if (!input) return "none" + if (typeof input !== "string" || !input) return "none" const ext = path.extname(input) const language = LANGUAGE_EXTENSIONS[ext] if (["typescriptreact", "javascriptreact", "javascript"].includes(language)) return "typescript" @@ -35,8 +35,14 @@ function EditBody(props: { request: PermissionRequest }) { const config = useTuiConfig() const dimensions = useTerminalDimensions() - const filepath = createMemo(() => (props.request.metadata?.filepath as string) ?? "") - const diff = createMemo(() => (props.request.metadata?.diff as string) ?? "") + const filepath = createMemo(() => { + const value = props.request.metadata?.filepath + return typeof value === "string" ? value : "" + }) + const diff = createMemo(() => { + const value = props.request.metadata?.diff + return typeof value === "string" ? value : "" + }) const view = createMemo(() => { const diffStyle = config.diff_style