JosefNemec/Playnite · error · Exception

result.Error

Error message

result.Error

What it means

Thrown by BaseServicesClient.ExecuteGetRequest<T> when a GET to the Playnite services endpoint returns a ServicesResponse<T> whose Error field is non-empty. The proxy/server reported an error in its payload, so the client logs it and re-throws as a plain Exception carrying the server's message.

Source

Thrown at source/Playnite/Services/BaseServicesClient.cs:40

            Timeout = new TimeSpan(0, 0, 60)
        };

        public BaseServicesClient(string endpoint, Version playniteVersion)
        {
            Endpoint = endpoint.TrimEnd('/');
            HttpClient.DefaultRequestHeaders.Add("Playnite-Version", playniteVersion.ToString(4));
        }

        public T ExecuteGetRequest<T>(string subUrl)
        {
            var url = Uri.EscapeUriString(Endpoint + subUrl);
            var strResult = HttpClient.GetStringAsync(url).GetAwaiter().GetResult();
            var result = Serialization.FromJson<ServicesResponse<T>>(strResult);

            if (!string.IsNullOrEmpty(result.Error))
            {
                logger.Error("Service request error by proxy: " + result.Error);
                throw new Exception(result.Error);
            }

            return result.Data;
        }

        public T ExecutePostRequest<T>(string subUrl, string jsonContent)
        {
            var url = Uri.EscapeUriString(Endpoint + subUrl);
            var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            var response = HttpClient.PostAsync(url, content).GetAwaiter().GetResult();
            var strResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            var result = Serialization.FromJson<ServicesResponse<T>>(strResult);

            if (!string.IsNullOrEmpty(result.Error))
            {
                logger.Error("Service request error by proxy: " + result.Error);
                throw new Exception(result.Error);
            }

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Inspect the logged message ('Service request error by proxy: ' + result.Error) and the server-side logs for the underlying cause.
  2. Validate the subUrl and query parameters (e.g. searchTerm, addonId) before calling.
  3. Confirm the Endpoint (ServicesUrl) and Playnite-Version header are correct for the target service.
  4. If transient (rate limit, backend restart), retry after a short delay; otherwise report the server error text.

Example fix

// before
var addons = client.ExecuteGetRequest<List<AddonManifest>>($"/addons?type={type}&searchTerm={searchTerm}".UrlEncode());

// after — sanitize input and surface server error
if (string.IsNullOrWhiteSpace(searchTerm)) throw new ArgumentException(nameof(searchTerm));
try { return client.ExecuteGetRequest<List<AddonManifest>>(...); }
catch (Exception ex) { logger.Error(ex, "Addons lookup failed"); throw; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check inputs before the GET:
if (string.IsNullOrWhiteSpace(subUrl)) throw new ArgumentException(nameof(subUrl));
// (server-side Error cannot be pre-validated; rely on try/catch)

Type guard

static bool LooksLikeValidSubUrl(string s) => !string.IsNullOrWhiteSpace(s) && s.StartsWith("/");

Try / catch

try { return client.ExecuteGetRequest<T>(subUrl); }
catch (Exception ex)
{
    logger.Error(ex, $"GET {subUrl} failed");
    if (IsTransient(ex.Message)) { await Task.Delay(backoff); return client.ExecuteGetRequest<T>(subUrl); }
    throw;
}

Prevention

When it happens

Trigger: ExecuteGetRequest hits Endpoint+subUrl, deserializes the JSON body into ServicesResponse<T>, and result.Error is non-empty at line 37. The server-side handler ran but failed (validation error, internal exception, rate limit, etc.).

Common situations: Addon/feature/patron lookup where the backend rejected the request (bad searchTerm, unknown addonId, DB error). Services proxy misconfigured or returning a 200-with-Error for upstream failures. Network returned an HTML error page that partially deserialized with Error set. Version header check server-side rejected the client.

Related errors


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/c2d30c82280aaf25. Report an issue: GitHub.