{"record":{"id":"b2383f5a7b70269d","repo":"Devolutions/UniGetUI","slug":"running-or-queued-operations-cannot-be-retried","errorCode":null,"errorMessage":"Running or queued operations cannot be retried.","messagePattern":"Running or queued operations cannot be retried\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"warning","filePath":"src/UniGetUI.Interface.IpcApi/IpcOperationApi.cs","lineNumber":215,"sourceCode":"    {\n        var tracked = GetTrackedOperation(operationId);\n        if (!IsActive(tracked.Operation.Status))\n        {\n            throw new InvalidOperationException(\n                \"Only queued or running operations can be canceled.\"\n            );\n        }\n\n        tracked.Operation.Cancel();\n        return IpcCommandResult.Success(\"cancel-operation\");\n    }\n\n    public static IpcCommandResult RetryOperation(string operationId, string? retryMode)\n    {\n        var tracked = GetTrackedOperation(operationId);\n        if (IsActive(tracked.Operation.Status))\n        {\n            throw new InvalidOperationException(\n                \"Running or queued operations cannot be retried.\"\n            );\n        }\n\n        string normalizedRetryMode = NormalizeRetryMode(retryMode);\n        var availableRetryModes = GetRetryModes(tracked.Operation);\n        if (!availableRetryModes.Contains(ToRetryModeName(normalizedRetryMode)))\n        {\n            throw new InvalidOperationException(\n                $\"Retry mode \\\"{retryMode}\\\" is not supported for operation {operationId}.\"\n            );\n        }\n\n        tracked.Operation.Retry(normalizedRetryMode);\n        return IpcCommandResult.Success(\"retry-operation\");\n    }\n\n    public static IpcCommandResult ReorderOperation(string operationId, string action)","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/Devolutions/UniGetUI/blob/9b1d7d0eab91620fc15c86b36676532095936ae3/src/UniGetUI.Interface.IpcApi/IpcOperationApi.cs#L197-L233","documentation":"Thrown by RetryOperation when the operation's status is InQueue or Running (IsActive returns true). Retrying an operation that is still active would create a duplicate or conflict. The operation must have reached a terminal state (succeeded, failed, or canceled) before retry is allowed.","triggerScenarios":"Calling RetryOperation for an operation that is still queued or running. The operation is found and active, so this guard fires before the retry-mode validation.","commonSituations":"Client retries an operation that appears stuck but is still technically Running. Race condition: the user clicks retry while the operation is mid-execution. UI shows a retry button for a running operation due to stale data.","solutions":["Wait for the operation to reach a terminal state (check via GetOperation or ListOperations polling).","Use the AvailableRetryModes field from IpcOperationInfo — it is empty for active operations, serving as a client-side indicator.","If the operation is truly stuck, call CancelOperation first, wait for it to register as canceled, then RetryOperation."],"exampleFix":"// before\nIpcOperationApi.RetryOperation(opId, \"retry\");\n// after\nvar info = IpcOperationApi.GetOperation(opId);\nif (info.AvailableRetryModes.Count > 0)\n    IpcOperationApi.RetryOperation(opId, info.AvailableRetryModes[0]);","handlingStrategy":"validation","validationCode":"var info = IpcOperationApi.GetOperation(operationId);\nif (info.AvailableRetryModes.Count == 0)\n    throw new InvalidOperationException($\"Operation {operationId} is still active and cannot be retried.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    IpcOperationApi.RetryOperation(operationId, retryMode);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"cannot be retried\"))\n{\n    // Still active — wait for terminal state\n    logger.LogWarning(\"Cannot retry {Id} yet: still active\", operationId);\n}","preventionTips":["Gate retry UI on AvailableRetryModes being non-empty.","Cancel the operation first if it is stuck, wait for terminal status, then retry.","Poll GetOperation to detect when the operation reaches a terminal state."],"tags":["operations","ipc","validation","state-machine"],"backgroundTag":null,"analyzedSha":"9b1d7d0eab91620fc15c86b36676532095936ae3","analyzedAt":"2026-08-13T12:19:18.278Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}