Skip to content

Commit 93d2670

Browse files
authored
🤖 Add forward compatibility for workspace path access (#273)
## Problem When switching between branches with different config formats, the app crashes with: ``` Cannot read properties of undefined (reading 'split') at AppInner (App.tsx:684:100) ``` This occurs because newer branches may add fields to the workspace config that older code doesn't expect (e.g., `namedWorkspacePath`, `id`, `name`). ## Solution Add optional chaining (`?.`) to all `workspacePath.split()` calls and provide sensible fallbacks: ```typescript // Before selectedWorkspace.workspacePath.split("/").pop() // After selectedWorkspace.workspacePath?.split("/").pop() ?? selectedWorkspace.workspaceId ``` ## Changes - **App.tsx**: Made `workspacePath` access defensive in ErrorBoundary and AIView - **utils/commands/sources.ts**: Made `workspacePath` access defensive in all command sources ## Testing - `make typecheck` passes ✅ - Allows switching between branches without config-related crashes - Handles both old format (only `path`) and new format (`id`, `name`, `path`) ## Impact This is a **defensive improvement** that makes the app more robust. No behavior changes for normal operation - only prevents crashes when config format mismatches occur.
1 parent 03ec5f3 commit 93d2670

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

src/App.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,15 +679,19 @@ function AppInner() {
679679
/>
680680
<MainContent>
681681
<ContentArea>
682-
{selectedWorkspace ? (
682+
{selectedWorkspace?.workspacePath ? (
683683
<ErrorBoundary
684-
workspaceInfo={`${selectedWorkspace.projectName}/${selectedWorkspace.workspacePath.split("/").pop() ?? ""}`}
684+
workspaceInfo={`${selectedWorkspace.projectName}/${selectedWorkspace.workspacePath?.split("/").pop() ?? selectedWorkspace.workspaceId ?? "unknown"}`}
685685
>
686686
<AIView
687687
key={selectedWorkspace.workspaceId}
688688
workspaceId={selectedWorkspace.workspaceId}
689689
projectName={selectedWorkspace.projectName}
690-
branch={selectedWorkspace.workspacePath.split("/").pop() ?? ""}
690+
branch={
691+
selectedWorkspace.workspacePath?.split("/").pop() ??
692+
selectedWorkspace.workspaceId ??
693+
""
694+
}
691695
workspacePath={selectedWorkspace.workspacePath}
692696
/>
693697
</ErrorBoundary>

src/utils/commands/sources.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
158158

159159
// Remove current workspace (rename action intentionally omitted until we add a proper modal)
160160
if (selected) {
161-
const workspaceDisplayName = `${selected.projectName}/${selected.workspacePath.split("/").pop() ?? selected.workspacePath}`;
161+
const workspaceDisplayName = `${selected.projectName}/${selected.workspacePath?.split("/").pop() ?? selected.workspacePath}`;
162162
list.push({
163163
id: "ws:open-terminal-current",
164164
title: "Open Current Workspace in Terminal",
@@ -193,8 +193,8 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
193193
name: "newName",
194194
label: "New name",
195195
placeholder: "Enter new workspace name",
196-
initialValue: selected.workspacePath.split("/").pop() ?? "",
197-
getInitialValue: () => selected.workspacePath.split("/").pop() ?? "",
196+
initialValue: selected.workspacePath?.split("/").pop() ?? "",
197+
getInitialValue: () => selected.workspacePath?.split("/").pop() ?? "",
198198
validate: (v) => (!v.trim() ? "Name is required" : null),
199199
},
200200
],
@@ -221,7 +221,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
221221
placeholder: "Search workspaces…",
222222
getOptions: () =>
223223
Array.from(p.workspaceMetadata.values()).map((meta) => {
224-
const workspaceName = meta.workspacePath.split("/").pop() ?? meta.workspacePath;
224+
const workspaceName = meta.workspacePath?.split("/").pop() ?? meta.workspacePath;
225225
const label = `${meta.projectName} / ${workspaceName}`;
226226
return {
227227
id: meta.workspacePath,
@@ -251,7 +251,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
251251
placeholder: "Search workspaces…",
252252
getOptions: () =>
253253
Array.from(p.workspaceMetadata.values()).map((meta) => {
254-
const workspaceName = meta.workspacePath.split("/").pop() ?? meta.workspacePath;
254+
const workspaceName = meta.workspacePath?.split("/").pop() ?? meta.workspacePath;
255255
const label = `${meta.projectName} / ${workspaceName}`;
256256
return {
257257
id: meta.id,
@@ -269,7 +269,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
269269
const meta = Array.from(p.workspaceMetadata.values()).find(
270270
(m) => m.id === values.workspaceId
271271
);
272-
return meta ? (meta.workspacePath.split("/").pop() ?? "") : "";
272+
return meta ? (meta.workspacePath?.split("/").pop() ?? "") : "";
273273
},
274274
validate: (v) => (!v.trim() ? "Name is required" : null),
275275
},
@@ -294,7 +294,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
294294
placeholder: "Search workspaces…",
295295
getOptions: () =>
296296
Array.from(p.workspaceMetadata.values()).map((meta) => {
297-
const workspaceName = meta.workspacePath.split("/").pop() ?? meta.workspacePath;
297+
const workspaceName = meta.workspacePath?.split("/").pop() ?? meta.workspacePath;
298298
const label = `${meta.projectName}/${workspaceName}`;
299299
return {
300300
id: meta.id,
@@ -309,7 +309,7 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi
309309
(m) => m.id === vals.workspaceId
310310
);
311311
const workspaceName = meta
312-
? `${meta.projectName}/${meta.workspacePath.split("/").pop() ?? meta.workspacePath}`
312+
? `${meta.projectName}/${meta.workspacePath?.split("/").pop() ?? meta.workspacePath}`
313313
: vals.workspaceId;
314314
const ok = confirm(`Remove workspace ${workspaceName}? This cannot be undone.`);
315315
if (ok) {

0 commit comments

Comments
 (0)