JosefNemec/Playnite · error · Exception

result.Error

Error message

result.Error

What it means

Thrown by ServicesClient.UploadDiagPackage when the POST to /playnite/diag returns a ServicesResponse<Guid> whose Error field is non-empty. The diagnostic-upload handler on the services proxy reported an error (size limit, server fault, storage failure), and the client re-throws the server's message.

Source

Thrown at source/Playnite/Services/ServicesClient.cs:51

        public List<string> GetPatrons()
        {
            return ExecuteGetRequest<List<string>>("/patreon/patrons");
        }

        public Guid UploadDiagPackage(string diagPath)
        {
            using (var fs = new FileStream(diagPath, FileMode.Open))
            {
                using (var content = new StreamContent(fs))
                {
                    var response = HttpClient.PostAsync(Endpoint + "/playnite/diag", content).GetAwaiter().GetResult();
                    var strResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    var result = JsonConvert.DeserializeObject<ServicesResponse<Guid>>(strResult);
                    if (!string.IsNullOrEmpty(result.Error))
                    {
                        logger.Error("Service request error by proxy: " + result.Error);
                        throw new Exception(result.Error);
                    }

                    return result.Data;
                }
            }
        }

        public List<AddonManifest> GetAllAddons(AddonType type, string searchTerm)
        {
            return ExecuteGetRequest<List<AddonManifest>>($"/addons?type={type}&searchTerm={searchTerm}".UrlEncode());
        }

        public AddonManifest GetAddon(string addonId)
        {
            return ExecuteGetRequest<List<AddonManifest>>($"/addons?addonId={addonId}".UrlEncode()).FirstOrDefault();
        }

        public AddonInstallerManifest GetAddonInstaller(string addonId)

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Read the captured Error text from the log to determine whether it's size, storage, or auth related.
  2. If the diag file is large, retry once after a backend restart or contact support; the server-side cap may need raising.
  3. Verify Endpoint (ServicesUrl) resolves to the current service and the Playnite-Version header is set.
  4. On persistent failure, fall back to saving the diag locally and sharing it manually.

Example fix

// before
var id = client.UploadDiagPackage(diagPath);

// after
try { return client.UploadDiagPackage(diagPath); }
catch (Exception ex)
{
    logger.Error(ex, "Diag upload failed; saving locally");
    File.Copy(diagPath, Path.Combine(localDir, Path.GetFileName(diagPath)));
    throw;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!File.Exists(diagPath)) throw new FileNotFoundException(diagPath);
var size = new FileInfo(diagPath).Length;
if (size > MaxDiagBytes) throw new InvalidOperationException($"Diag package too large: {size}");

Type guard

static bool CanUploadDiag(string path) => File.Exists(path) && new FileInfo(path).Length <= MaxDiagBytes;

Try / catch

try { return client.UploadDiagPackage(diagPath); }
catch (Exception ex)
{
    logger.Error(ex, "Diag upload failed; keep local copy");
    File.Copy(diagPath, Path.Combine(localFallbackDir, Path.GetFileName(diagPath)), overwrite: true);
    throw;
}

Prevention

When it happens

Trigger: UploadDiagPackage(diagPath) POSTs the file stream to Endpoint+'/playnite/diag'; the response body deserializes with a non-empty Error at line 48. The server accepted the connection but failed to ingest the package.

Common situations: Diag package exceeds the server's max body size. Backend storage (blob/db) temporarily unavailable. ServicesUrl points to a stale endpoint that returns an error envelope. Auth/anti-abuse layer on the proxy rejected the upload.

Related errors


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