{"record":{"id":"ac76dfac14bb1aac","repo":"agalwood/Motrix","slug":"tasknotfound-ac76df","errorCode":"TaskNotFound","errorMessage":"task ${taskId} not found for magnet metadata swap","messagePattern":"task (.+?) not found for magnet metadata swap","errorType":"exception","errorClass":"AppError","httpStatus":null,"severity":"warning","filePath":"src/core/torrent/swap-magnet-metadata-for-bt.ts","lineNumber":127,"sourceCode":"  input: SwapMagnetMetadataInput,\n  deps: SwapMagnetMetadataDeps\n): Promise<{ gid: string }> {\n  const { taskId, base64, selectedFiles, saveDir, name } = input\n  const {\n    db,\n    taskManager,\n    adapter,\n    magnetTracker,\n    finalNamePicker,\n    torrentMetaStore,\n    publishTaskUpdate,\n    publishTaskUpdateNow,\n    recordTransition,\n  } = deps\n\n  const existing = db.getTask(taskId)\n  if (!existing) {\n    throw new AppError(\n      ErrorCode.TaskNotFound,\n      `task ${taskId} not found for magnet metadata swap`\n    )\n  }\n\n  if (\n    magnetTracker.hasPendingSwapCleanup(taskId) ||\n    existing.instances.some(isMagnetCleanupTombstoneHidden)\n  ) {\n    throw new AppError(\n      ErrorCode.MagnetCleanupPending,\n      `aria2 cleanup for a failed magnet swap is still pending for ` +\n        `task ${taskId}; please retry confirmation shortly.`\n    )\n  }\n  const previousMetadataInstance =\n    existing.instances.length === 1 ? existing.instances[0] : undefined\n  if (","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/torrent/swap-magnet-metadata-for-bt.ts#L109-L145","documentation":"Thrown by swap-magnet-metadata-for-bt.ts:127 when `db.getTask(taskId)` returns null at the entry of a magnet-metadata-swap operation. The task targeted for swapping its MetadataReady magnet instance for a bt_download instance does not exist.","triggerScenarios":"Swap requested for a taskId that was deleted between the user confirming and the swap call; a stale UI confirmation window; a typoed/fabricated taskId from an external caller; the task was cleared by clear-stopped-tasks.","commonSituations":"User confirmed a file selection, then deleted the task before the swap ran; renderer holding a stale task reference after a bulk clear; cross-window IPC with an outdated id.","solutions":["Verify the task exists in the renderer before showing the swap confirmation, and dismiss the dialog on task-deleted events.","Treat TaskNotFound as a clean no-op (log + close the window) instead of a hard error.","Guard the IPC entrypoint with a presence check and return a benign error to the renderer.","Ensure clear-stopped-tasks and swap cannot run against the same task concurrently."],"exampleFix":"// before\nconst existing = db.getTask(taskId)\nif (!existing) {\n  throw new AppError(ErrorCode.TaskNotFound, `task ${taskId} not found for magnet metadata swap`)\n}\n\n// after — benign no-op for stale confirmations\nconst existing = db.getTask(taskId)\nif (!existing) {\n  deps.log.warn({ taskId }, 'swap ignored: task no longer exists')\n  return { outcome: 'noop', reason: 'task_missing' }\n}","handlingStrategy":"validation","validationCode":"function swapTargetExists(db, taskId) { return Boolean(db.getTask(taskId)) }","typeGuard":"function isSwapTaskNotFound(e) { return e instanceof AppError && e.code === ErrorCode.TaskNotFound && /magnet metadata swap/.test(e.message) }","tryCatchPattern":"const existing = db.getTask(taskId)\nif (!existing) {\n  deps.log.warn({ taskId }, 'swap ignored: task no longer exists')\n  return { outcome: 'noop', reason: 'task_missing' }\n}","preventionTips":["Verify the task exists in the renderer before showing the swap confirmation.","Dismiss the swap dialog on task-deleted events.","Treat TaskNotFound as a benign no-op at this entrypoint.","Prevent clear-stopped-tasks and swap from racing on the same task."],"tags":["magnet","swap","task-lifecycle","state","ui-race"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}