Devolutions/UniGetUI · warning · InvalidOperationException
Timed out while waiting for operation {operationId}.
Error message
Timed out while waiting for operation {operationId}. What it means
Thrown inside IpcClient.WaitForOperationAsync when the polling deadline (DateTime.UtcNow >= deadline) is reached before the operation reaches a terminal status (succeeded/failed/canceled). The deadline is startTime + Clamp(timeoutSeconds,1,3600), checked once per loop iteration after each poll.
Source
Thrown at src/UniGetUI.Interface.IpcApi/IpcClient.cs:186
DateTime deadline = DateTime.UtcNow.AddSeconds(timeoutSeconds);
while (true)
{
var operation = await GetOperationAsync(operationId)
?? throw new InvalidOperationException(
$"No tracked operation with id \"{operationId}\" was found."
);
if (
operation.Status is "succeeded" or "failed" or "canceled"
)
{
return operation;
}
if (DateTime.UtcNow >= deadline)
{
throw new InvalidOperationException(
$"Timed out while waiting for operation {operationId}."
);
}
await Task.Delay(delayMilliseconds);
}
}
public async Task<IpcCommandResult> CancelOperationAsync(string operationId)
{
return await ReadAuthenticatedJsonAsync<IpcCommandResult>(
HttpMethod.Post,
IpcHttpRoutes.Path($"/operations/{Uri.EscapeDataString(operationId)}/cancel")
)
?? new IpcCommandResult
{
Status = "error",
Command = "cancel-operation",View on GitHub (pinned to 9b1d7d0eab)
Solutions
- Increase timeoutSeconds (up to the 3600 clamp) when calling WaitForOperationAsync for long operations.
- Call CancelOperationAsync then resubmit if the operation is genuinely hung.
- Check the operation output endpoint for clues about what it is blocked on.
- Lower delayMilliseconds to poll more frequently and react sooner to completion.
Example fix
// before var result = await client.WaitForOperationAsync(id); // 300s default // after var result = await client.WaitForOperationAsync(id, timeoutSeconds: 1800);
Defensive patterns
Strategy: retry
Validate before calling
// Choose timeout based on expected operation cost:
int timeout = operationKind switch
{
"install" or "uninstall" => 1800, // long-running
_ => 300,
}; Try / catch
try { await client.WaitForOperationAsync(id, timeoutSeconds: 1800); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Timed out"))
{ /* inspect output, cancel if hung, or retry with a longer timeout */ } Prevention
- Scale timeoutSeconds to the worst-case operation duration (clamped to 3600).
- Cancel and resubmit operations that are genuinely hung rather than extending the timeout indefinitely.
- Poll operation output to detect interactive prompts blocking completion.
When it happens
Trigger: An operation that runs longer than the supplied timeoutSeconds (default 300). A long package install/uninstall on a slow manager, a hung elevated process, or an operation stuck in a non-terminal status. Also if delayMilliseconds is large relative to timeout so few polls occur.
Common situations: Large bundle installs exceeding the 5-minute default. Network-bound managers (pip, npm) slow on cold cache. An operation whose manager process is awaiting interactive input and never returns. Defaulting to the 300s timeout for genuinely long tasks.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- No tracked operation with id "{operationId}" was found.
- string.IsNullOrWhiteSpace(content) ? response.ReasonPhrase :
- The Unix socket path is not available for the named-pipe tra
- The IPC API token is not available. Start UniGetUI and try a
- tailLines must be greater than or equal to zero.
AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13).
Data as JSON: /api/errors/c95434c115ddc5cf.
Report an issue: GitHub.