agalwood/Motrix · error · AppError
MagnetCleanupPending
MagnetCleanupPending
Error message
aria2 cleanup for a failed magnet swap is still pending for task ${taskId}; please retry confirmation shortly. What it means
Thrown by swap-magnet-metadata-for-bt.ts:137 when either `magnetTracker.hasPendingSwapCleanup(taskId)` is true or one of the task's instances is a hidden magnet-cleanup tombstone. A previous swap failed and aria2 cleanup of the orphaned GID is still quarantined, so starting a new swap now would create a sibling GID while the old one is still being torn down.
Source
Thrown at src/core/torrent/swap-magnet-metadata-for-bt.ts:137
torrentMetaStore,
publishTaskUpdate,
publishTaskUpdateNow,
recordTransition,
} = deps
const existing = db.getTask(taskId)
if (!existing) {
throw new AppError(
ErrorCode.TaskNotFound,
`task ${taskId} not found for magnet metadata swap`
)
}
if (
magnetTracker.hasPendingSwapCleanup(taskId) ||
existing.instances.some(isMagnetCleanupTombstoneHidden)
) {
throw new AppError(
ErrorCode.MagnetCleanupPending,
`aria2 cleanup for a failed magnet swap is still pending for ` +
`task ${taskId}; please retry confirmation shortly.`
)
}
const previousMetadataInstance =
existing.instances.length === 1 ? existing.instances[0] : undefined
if (
existing.task.taskType !== TaskType.Magnet ||
existing.task.aggStatus !== TaskStatus.MetadataReady ||
previousMetadataInstance?.phase !==
TaskInstancePhase.MagnetMetadataResolution ||
previousMetadataInstance.status !== TaskStatus.MetadataReady
) {
throw new AppError(
ErrorCode.InvalidSelection,
`task ${taskId} is not a MetadataReady magnet selection`
)View on GitHub (pinned to 1a708ee577)
Solutions
- Wait a short interval and retry — the cleanup worker reaps the quarantine and the tombstone clears automatically.
- Confirm aria2 is healthy and reachable so the pending cleanup can complete.
- Surface a user-facing 'cleanup in progress, retry shortly' message instead of a raw error.
- Disable the confirm button while `magnetTracker.hasPendingSwapCleanup(taskId)` is true.
Example fix
// before
if (magnetTracker.hasPendingSwapCleanup(taskId) || existing.instances.some(isMagnetCleanupTombstoneHidden)) {
throw new AppError(ErrorCode.MagnetCleanupPending, `aria2 cleanup for a failed magnet swap is still pending for task ${taskId}; please retry confirmation shortly.`)
}
// after — UI-driven backoff retry
async function swapWithBackoff(taskId, deps) {
for (let attempt = 0; attempt < 5; attempt++) {
try { return await swapMagnetMetadata(taskId, deps) }
catch (e) {
if (e instanceof AppError && e.code === ErrorCode.MagnetCleanupPending && attempt < 4) {
await delay(1000 * (attempt + 1)); continue
}
throw e
}
}
} Defensive patterns
Strategy: retry
Validate before calling
function swapCleanupDone(magnetTracker, existing, taskId) {
return !magnetTracker.hasPendingSwapCleanup(taskId)
&& !existing.instances.some(isMagnetCleanupTombstoneHidden)
} Type guard
function isSwapCleanupPending(e) { return e instanceof AppError && e.code === ErrorCode.MagnetCleanupPending && /failed magnet swap/.test(e.message) } Try / catch
for (let attempt = 0; attempt < 5; attempt++) {
try { return await swapMagnetMetadata(taskId, deps) }
catch (e) {
if (e instanceof AppError && e.code === ErrorCode.MagnetCleanupPending && attempt < 4) {
await delay(1000 * (attempt + 1)); continue
}
throw e
}
} Prevention
- Wait a short interval and retry — the cleanup worker drains the quarantine.
- Disable the confirm button while hasPendingSwapCleanup(taskId) is true.
- Confirm aria2 is healthy so cleanup can complete.
- Surface a user-facing 'cleanup in progress, retry shortly' message.
When it happens
Trigger: User retries the swap immediately after a previous failed swap whose aria2 RPC cleanup returned 'quarantined'; a transient RPC failure left the swap cleanup tombstone in place; the magnet-cleanup worker has not yet finished reaping the old GID.
Common situations: Impatient retry after a failed swap; aria2 briefly unreachable (RPC timeout) during cleanup; rapid double-click of the confirm button.
Related errors
- aria2 returned gid ${actualGid} instead of reserved gid ${re
- TaskNotFound
- InvalidSelection
- aria2 addTorrent gid must contain exactly 16 hexadecimal cha
- EngineProtocolError
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/f432cb0947028f14.
Report an issue: GitHub.