{"record":{"id":"37ff63b49d9f030b","repo":"paperclipai/paperclip","slug":"failed-run-is-no-longer-available","errorCode":null,"errorMessage":"Failed run is no longer available.","messagePattern":"Failed run is no longer available\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/pages/IssueDetail.tsx","lineNumber":1510,"sourceCode":"    setDiscardedQueuedCommentIds(new Set());\n  }, [issueId]);\n  useEffect(() => {\n    setLocalSteeringPlacements(new Map());\n  }, [issueId]);\n  const hasLiveRuns = liveRunCount > 0 || !!resolvedActiveRun;\n  const { data: linkedRuns, isPending: linkedRunsPending, isError: linkedRunsError, refetch: refetchLinkedRuns } = useQuery({\n    queryKey: queryKeys.issues.runs(issueId),\n    queryFn: () => activityApi.runsForIssue(issueId),\n    refetchInterval:\n      hasLiveRuns || issueStatus === \"in_progress\" ? 1000 : false,\n    placeholderData: keepPreviousDataForSameQueryTail<RunForIssue[]>(issueId),\n  });\n  const resolvedActivity = activity ?? [];\n  const resolvedLinkedRuns = linkedRuns ?? [];\n  const retryFailedRun = useMutation({\n    mutationFn: async (runId: string) => {\n      const failedRun = resolvedLinkedRuns.find((run) => run.runId === runId);\n      if (!failedRun) throw new Error(\"Failed run is no longer available.\");\n      const result = await agentsApi.wakeup(\n        failedRun.agentId,\n        {\n          source: \"on_demand\",\n          triggerDetail: \"manual\",\n          reason: \"retry_failed_run\",\n          payload: { issueId },\n        },\n        companyId,\n      );\n      if (!(\"id\" in result)) {\n        throw new Error(result.message ?? \"Retry was skipped.\");\n      }\n      return result;\n    },\n    onSuccess: () => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.issues.runs(issueId),","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/pages/IssueDetail.tsx#L1492-L1528","documentation":"retryFailedRun in IssueDetail looks up the run to retry in resolvedLinkedRuns by runId. If the run is no longer present in the issue's linked runs (deleted, unlinked, or the list is stale), the mutation throws this error instead of calling agentsApi.wakeup. It guards against retrying a run the issue no longer references.","triggerScenarios":"retryFailedRun.mutate(runId) with a runId not found in resolvedLinkedRuns — the linked-runs query returned data without that run (stale cache, run deleted, or list not yet loaded when resolvedLinkedRuns defaulted to []).","commonSituations":"Clicking Retry on an outdated activity/linked-run entry after another actor removed the run; the linked-runs query failed or was still loading so the fallback empty array was used; issue data refreshed between render and click.","solutions":["Invalidate/refetch the issue's linked runs and retry once the list is current.","Verify the run still exists (it may have been deleted or unlinked from the issue) and pick the current entry.","Guard the Retry button on the run being present in the current linkedRuns data.","If the linked-runs query errored, surface that error instead of silently using the empty fallback."],"exampleFix":"// before\nconst failedRun = resolvedLinkedRuns.find((run) => run.runId === runId);\nif (!failedRun) throw new Error(\"Failed run is no longer available.\");\n// after (refresh then retry)\nconst failedRun = resolvedLinkedRuns.find((run) => run.runId === runId);\nif (!failedRun) {\n  await queryClient.invalidateQueries({ queryKey: queryKeys.issues.runs(issueId) });\n  throw new Error(\"Failed run is no longer available.\");\n}","handlingStrategy":"validation","validationCode":"const failedRun = resolvedLinkedRuns.find((run) => run.runId === runId);\nif (!failedRun) {\n  await queryClient.invalidateQueries({ queryKey: queryKeys.issues.runs(issueId) });\n  toast.info(\"Run list refreshed — retry again if the run is still listed.\");\n  return;\n}","typeGuard":"const isLinked = (runs: { runId: string }[], id: string) => runs.some((r) => r.runId === id);","tryCatchPattern":"try {\n  await retryFailedRun.mutateAsync(runId);\n} catch (e) {\n  toast.error(e.message);\n  await queryClient.invalidateQueries({ queryKey: queryKeys.issues.runs(issueId) });\n}","preventionTips":["Only render Retry for runs present in the current linkedRuns data.","Invalidate issue run queries after any actor action that can add/remove linked runs.","Avoid rendering retry actions from cached snapshots without a freshness check."],"tags":["ui","stale-data","run-lifecycle","guard"],"backgroundTag":"record-not-found","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}