Devolutions/UniGetUI · error · InvalidOperationException

string.IsNullOrWhiteSpace(content) ? response.ReasonPhrase :

Error message

string.IsNullOrWhiteSpace(content) ? response.ReasonPhrase : content

What it means

Thrown by IpcClient.SendAsync whenever the HTTP response status is not success (2xx). The exception message is the response body if non-blank, otherwise the HTTP reason phrase. This is the generic non-OK gateway: every IPC call that fails server-side surfaces here with whatever the server wrote.

Source

Thrown at src/UniGetUI.Interface.IpcApi/IpcClient.cs:1079

        return await SendAsync(method, relativePath, parameters, requestContent);
    }

    private async Task<string> SendAsync(
        HttpMethod method,
        string relativePath,
        IReadOnlyDictionary<string, string>? queryParameters = null,
        HttpContent? requestContent = null
    )
    {
        using var timeout = new CancellationTokenSource(GetRequestTimeout(method, relativePath));
        using var request = new HttpRequestMessage(method, BuildRelativeUri(relativePath, queryParameters));
        request.Content = requestContent;
        using var response = await _httpClient.SendAsync(request, timeout.Token);
        string content = await response.Content.ReadAsStringAsync();

        if (!response.IsSuccessStatusCode)
        {
            throw new InvalidOperationException(
                string.IsNullOrWhiteSpace(content) ? response.ReasonPhrase : content
            );
        }

        return content;
    }

    private async Task<T?> ReadAuthenticatedJsonAsync<T>(
        HttpMethod method,
        string relativePath,
        IReadOnlyDictionary<string, string>? queryParameters = null
    )
    {
        string json = await SendAuthenticatedAsync(method, relativePath, queryParameters);
        return IpcJson.Deserialize<T>(json);
    }

    private async Task<TResponse?> ReadAuthenticatedJsonWithBodyAsync<TResponse, TBody>(

View on GitHub (pinned to 9b1d7d0eab)

Solutions

  1. Inspect the exception Message: if non-empty it is the server's response body, which usually names the real problem.
  2. Confirm the IPC token is current (re-discover it from the running UniGetUI session).
  3. Call GetStatusAsync first to confirm the server is alive and the token is accepted.
  4. Map the HTTP status: 401/403 -> token/secure-settings; 404 -> wrong id/route; 5xx -> server log.
  5. Wrap IPC calls and log ex.Message plus the relative path to correlate with server logs.
Defensive patterns

Strategy: try-catch

Validate before calling

// Liveness + auth probe before protected calls:
var status = await client.GetStatusAsync();
if (!status.Running) { /* server unavailable */ }

Try / catch

try { return await client.SendSomethingAsync(...); }
catch (InvalidOperationException ex)
{
    // ex.Message is the server response body (or HTTP reason phrase).
    logger.LogError("IPC call failed: {Message}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Any IPC request returning 4xx/5xx: 401/403 when the token is wrong or SecureSettings denies the action, 404 for unknown routes/ids, 400 for server-side validation failures, 500 for unhandled server exceptions, 503 when the backend manager process is unavailable. The token is attached as a query parameter before this call.

Common situations: Token mismatch after UniGetUI regenerated the IPC token on restart. Hitting an endpoint gated by a SecureSettings flag that is off. Server-side InvalidOperationException (errors 20-23, 33-39) propagated as a 400/500 body. Manager executable missing producing a server error. Network reset returning a non-success code.

Related errors


AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13). Data as JSON: /api/errors/1951f8604125a515. Report an issue: GitHub.