Skip to content

Commit f3f1bdc

Browse files
committed
fix(aio): honor task detail 404 only on cold cache misses
The task detail routes redirected away on any 404 from the detail query, even when a cached or list copy of the task exists. Optimistic and cloud-pending tasks are not returnable by the API yet (see the route loader comments), so the unconditional redirect kicked users off tasks they had just created. The detail query still always runs (so a stale cached copy converges on the server's latest run state), but a 404/missing result only triggers the redirect when there is no usable cached task to render. Generated-By: PostHog Code Task-Id: 0c511836-2180-455a-9b58-45df2a0661ec
1 parent 4b92e4e commit f3f1bdc

2 files changed

Lines changed: 14 additions & 13 deletions

File tree

packages/ui/src/router/routes/code/tasks/$taskId.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { TaskDetail } from "@posthog/ui/features/task-detail/components/TaskDeta
33
import {
44
getCachedTask,
55
getCachedTaskDetail,
6-
isTaskDetailNotFoundError,
76
taskDetailQuery,
87
} from "@posthog/ui/features/tasks/queries";
98
import { pickFreshestTask } from "@posthog/ui/features/tasks/taskFreshness";
@@ -41,25 +40,24 @@ function TaskDetailRoute() {
4140
const fromList = tasks?.find((t) => t.id === taskId);
4241
const initialTask = pickFreshestTask(fromList, loaderTask);
4342

44-
// Cold deep-link / URL restore: nothing cached. Fetch the single task here so
45-
// a hang or 404 only affects this view's spinner, never the router.
46-
const needsFetch = !initialTask;
43+
// Always fetch so a stale cached copy converges on the server's latest run
44+
// state; render whichever copy is freshest.
4745
const {
4846
data: fetched,
49-
error,
5047
isError,
5148
isSuccess,
5249
} = useQuery(taskDetailQuery(taskId));
5350

5451
const task = pickFreshestTask(fetched, initialTask);
5552

56-
// Task doesn't exist (deleted, 404, or stale deep link): the cold fetch
57-
// settled with an error or empty result. Redirect to the new-task screen
58-
// rather than spin forever — matches the old navigationStore.hydrateTask.
59-
if (
60-
isTaskDetailNotFoundError(error) ||
61-
(needsFetch && (isError || (isSuccess && !fetched)))
62-
) {
53+
// Cold deep-link / URL restore with nothing cached: if the fetch settled
54+
// with an error or empty result, redirect to the new-task screen rather
55+
// than spin forever — matches the old navigationStore.hydrateTask. While a
56+
// cached/list copy exists, a 404 is NOT authoritative (optimistic and
57+
// cloud-pending tasks aren't returnable by the API yet — see the loader
58+
// comment), so never redirect away from a usable task.
59+
const needsFetch = !initialTask;
60+
if (needsFetch && (isError || (isSuccess && !fetched))) {
6361
return <Navigate replace to="/code" />;
6462
}
6563

packages/ui/src/router/routes/website/$channelId/tasks/$taskId.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ function ChannelTaskDetailRoute() {
7373

7474
const task = pickFreshestTask(fetched, initialTask);
7575

76-
if (isTaskDetailNotFoundError(error)) {
76+
// While a cached/list copy exists, a 404 is NOT authoritative (optimistic
77+
// and cloud-pending tasks aren't returnable by the API yet — see the loader
78+
// comment), so only treat the task as gone when nothing cached is usable.
79+
if (!initialTask && isTaskDetailNotFoundError(error)) {
7780
return <Navigate replace to="/website/$channelId" params={{ channelId }} />;
7881
}
7982

0 commit comments

Comments
 (0)