Devolutions/UniGetUI · warning · InvalidOperationException
Running or queued operations cannot be forgotten.
Error message
Running or queued operations cannot be forgotten.
What it means
Thrown by ForgetOperation when the operation's status is InQueue or Running (IsActive returns true). Forgetting removes an operation from the tracking dictionary, which is only safe for terminal operations. Active operations must be canceled first and allowed to reach a terminal state before they can be forgotten.
Source
Thrown at src/UniGetUI.Interface.IpcApi/IpcOperationApi.cs:266
case "run-next":
tracked.Operation.RunNext();
break;
case "run-last":
tracked.Operation.BackOfTheQueue();
break;
default:
throw new InvalidOperationException($"Unsupported queue action \"{action}\".");
}
return IpcCommandResult.Success("reorder-operation");
}
public static IpcCommandResult ForgetOperation(string operationId)
{
var tracked = GetTrackedOperation(operationId);
if (IsActive(tracked.Operation.Status))
{
throw new InvalidOperationException(
"Running or queued operations cannot be forgotten."
);
}
ForgetTracking(operationId);
return IpcCommandResult.Success("forget-operation");
}
public static void ForgetTracking(string operationId)
{
Operations.TryRemove(operationId, out _);
}
private static TrackedOperation GetTrackedOperation(string operationId)
{
ArgumentException.ThrowIfNullOrWhiteSpace(operationId);
return Operations.TryGetValue(operationId.Trim(), out var tracked)View on GitHub (pinned to 9b1d7d0eab)
Solutions
- Check CanForget (or AvailableRetryModes being non-empty implies terminal) before calling ForgetOperation.
- If the operation is active, call CancelOperation first, wait for status to change, then ForgetOperation.
- Use the pruning mechanism (MaxTrackedOperations = 200) for automatic cleanup of old completed operations instead of manual forgetting.
Example fix
// before — forget without checking state
IpcOperationApi.ForgetOperation(opId);
// after
var info = IpcOperationApi.GetOperation(opId);
if (info.CanForget)
IpcOperationApi.ForgetOperation(opId);
else
IpcOperationApi.CancelOperation(opId); // cancel first, forget later Defensive patterns
Strategy: validation
Validate before calling
var info = IpcOperationApi.GetOperation(operationId);
if (!info.CanForget)
throw new InvalidOperationException($"Operation {operationId} is still active. Cancel it first."); Prevention
- Gate forget UI on the CanForget field from IpcOperationInfo.
- Cancel active operations first, wait for terminal status, then forget.
- Rely on the automatic pruning (MaxTrackedOperations=200) for routine cleanup.
When it happens
Trigger: Calling ForgetOperation for an operation that is still queued or running. The operation is found via GetTrackedOperation but its status indicates it is active. CanForget on IpcOperationInfo is false for active operations.
Common situations: Client attempts to clean up the operations list while operations are still in progress. Race condition: operation finishes between status check and forget call. Forgetting an operation that is InQueue but hasn't started executing yet.
Related errors
- Only queued or running operations can be canceled.
- Running or queued operations cannot be retried.
- Only queued operations can be reordered.
- tailLines must be greater than or equal to zero.
- Retry mode "{retryMode}" is not supported for operation {ope
AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13).
Data as JSON: /api/errors/723a069f961613dc.
Report an issue: GitHub.