Fix workspace actions in summary (#1986)

## Summary

Fixed the "workspace not found" error when performing actions on non-selected workspaces.

**Root cause**: The `getWorkspaceFromCache()` function only checked the React Query cache, but only the currently selected workspace had its full data cached.

**Solution**: Modified the helper function to fetch from the API when data isn't in cache.

**File modified**: `frontend/src/components/ui-new/actions/index.ts`

**Changes**:
1. Renamed `getWorkspaceFromCache` → `getWorkspace` and made it async
2. Added fallback to `attemptsApi.get(workspaceId)` when cache miss occurs
3. Updated all 6 call sites to use `await getWorkspace()`:
   - `RenameWorkspace` (line 215)
   - `PinWorkspace` (line 229)
   - `ArchiveWorkspace` (line 246)
   - `DeleteWorkspace` (line 281)
   - `OpenInOldUI` (line 489)
   - `GitCreatePR` (line 630)
This commit is contained in:
Louis Knight-Webb
2026-01-12 23:02:56 +00:00
committed by GitHub
parent b87fb13e87
commit 25c8ab29a9

View File

@@ -161,18 +161,19 @@ export type ActionDefinition =
| WorkspaceActionDefinition
| GitActionDefinition;
// Helper to get workspace from query cache
function getWorkspaceFromCache(
// Helper to get workspace from query cache or fetch from API
async function getWorkspace(
queryClient: QueryClient,
workspaceId: string
): Workspace {
const workspace = queryClient.getQueryData<Workspace>(
): Promise<Workspace> {
const cached = queryClient.getQueryData<Workspace>(
attemptKeys.byId(workspaceId)
);
if (!workspace) {
throw new Error('Workspace not found');
if (cached) {
return cached;
}
return workspace;
// Fetch from API if not in cache
return attemptsApi.get(workspaceId);
}
// Helper to invalidate workspace-related queries
@@ -211,7 +212,7 @@ export const Actions = {
icon: PencilSimpleIcon,
requiresTarget: true,
execute: async (ctx, workspaceId) => {
const workspace = getWorkspaceFromCache(ctx.queryClient, workspaceId);
const workspace = await getWorkspace(ctx.queryClient, workspaceId);
await RenameWorkspaceDialog.show({
workspaceId,
currentName: workspace.name || workspace.branch,
@@ -225,7 +226,7 @@ export const Actions = {
icon: PushPinIcon,
requiresTarget: true,
execute: async (ctx, workspaceId) => {
const workspace = getWorkspaceFromCache(ctx.queryClient, workspaceId);
const workspace = await getWorkspace(ctx.queryClient, workspaceId);
await attemptsApi.update(workspaceId, {
pinned: !workspace.pinned,
});
@@ -242,7 +243,7 @@ export const Actions = {
isVisible: (ctx) => ctx.hasWorkspace,
isActive: (ctx) => ctx.workspaceArchived,
execute: async (ctx, workspaceId) => {
const workspace = getWorkspaceFromCache(ctx.queryClient, workspaceId);
const workspace = await getWorkspace(ctx.queryClient, workspaceId);
const wasArchived = workspace.archived;
// Calculate next workspace before archiving
@@ -277,7 +278,7 @@ export const Actions = {
variant: 'destructive',
requiresTarget: true,
execute: async (ctx, workspaceId) => {
const workspace = getWorkspaceFromCache(ctx.queryClient, workspaceId);
const workspace = await getWorkspace(ctx.queryClient, workspaceId);
const result = await ConfirmDialog.show({
title: 'Delete Workspace',
message:
@@ -485,7 +486,7 @@ export const Actions = {
return;
}
const workspace = getWorkspaceFromCache(
const workspace = await getWorkspace(
ctx.queryClient,
ctx.currentWorkspaceId
);
@@ -626,7 +627,7 @@ export const Actions = {
requiresTarget: 'git',
isVisible: (ctx) => ctx.hasWorkspace && ctx.hasGitRepos,
execute: async (ctx, workspaceId, repoId) => {
const workspace = getWorkspaceFromCache(ctx.queryClient, workspaceId);
const workspace = await getWorkspace(ctx.queryClient, workspaceId);
const task = await tasksApi.getById(workspace.task_id);
const repos = await attemptsApi.getRepos(workspaceId);