{"record":{"id":"e7f7d8eb65b54311","repo":"paperclipai/paperclip","slug":"the-task-is-not-available-for-reassignment","errorCode":null,"errorMessage":"The task is not available for reassignment.","messagePattern":"The task is not available for reassignment\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/components/TaskChatThread.tsx","lineNumber":557,"sourceCode":"  const effectiveGoalAgentId =\n    pendingComposerAssignee === null\n      ? issueAssigneeAgentId\n      : pendingComposerAssignee.startsWith(\"agent:\")\n        ? pendingComposerAssignee.slice(\"agent:\".length) || null\n        : null;\n  const runnerGoal = useRunnerGoalControl(issueId, effectiveGoalAgentId);\n\n  useEffect(() => {\n    setPendingComposerAssignee(null);\n  }, [currentAssigneeValue, issueId]);\n\n  const reassignForRunnerGoal = useCallback(\n    async (reassignment: {\n      assigneeAgentId: string | null;\n      assigneeUserId: string | null;\n    }) => {\n      if (!issueId)\n        throw new Error(\"The task is not available for reassignment.\");\n      await issuesApi.update(issueId, { ...reassignment, deferWakeForGoal: true });\n      await queryClient.invalidateQueries({\n        queryKey: queryKeys.issues.detail(issueId),\n      });\n    },\n    [issueId, queryClient],\n  );\n\n  const queuedMessageQueue =\n    queuedCommentQueue && queuedCommentQueue.entries.length > 0\n      ? queuedCommentQueue\n      : null;\n  const queuedCommentIds = useMemo(\n    () =>\n      new Set(\n        queuedMessageQueue?.entries.map((entry) => entry.comment.id) ?? [],\n      ),\n    [queuedMessageQueue],","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/components/TaskChatThread.tsx#L539-L575","documentation":"TaskChatThread's reassignForRunnerGoal callback throws this fixed message when reassignment is requested but issueId is undefined. Without an issue id the issuesApi.update call cannot target a task, so the callback refuses to proceed.","triggerScenarios":"The reassignment UI (runner-goal flow) invokes onReassign while the thread is rendered outside a loaded issue context — issueId prop is null/undefined (draft thread, detached view, or issue failed to load).","commonSituations":"Rendering TaskChatThread in a preview/draft state where no issue is persisted yet, issue deleted before reassignment completes, race where the panel renders before issueId is resolved.","solutions":["Ensure TaskChatThread is only mounted with a valid issueId","Disable reassign controls until the issue detail query resolves","Guard the caller: check issueId before invoking reassignment"],"exampleFix":"// before\nif (!issueId) throw new Error(\"The task is not available for reassignment.\");\n// after\nif (!issueId) {\n  toastActions?.pushToast({ title: \"Save the task before reassigning\", tone: \"warning\" });\n  return;\n}","handlingStrategy":"validation","validationCode":"if (!issueId) { showToast('No task loaded'); return; }","typeGuard":"function hasIssueId(p: { issueId?: string | null }): p is { issueId: string } { return typeof p.issueId === 'string' && p.issueId.length > 0; }","tryCatchPattern":"try { await reassignForRunnerGoal({ assigneeAgentId, assigneeUserId }); } catch (e) { if (/not available for reassignment/.test(e.message)) showToast('Open a saved task first'); else throw e; }","preventionTips":["Render reassignment controls only when issue detail is loaded","Disable the panel in draft/preview modes","Type issueId as required in mounted-thread props","Wait for the issues detail query before enabling mutations"],"tags":["ui-state","reassignment","null-check"],"backgroundTag":"missing-required-argument","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"}