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
- Read the captured Error text from the log to determine whether it's size, storage, or auth related.
- If the diag file is large, retry once after a backend restart or contact support; the server-side cap may need raising.
- Verify Endpoint (ServicesUrl) resolves to the current service and the Playnite-Version header is set.
- 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
- Check diag file size against the server cap before upload.
- Keep a local copy on failure so diagnostics aren't lost.
- Verify the ServicesUrl endpoint is current.
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
- result.Error
- Failed to download string from all mirrors.
- Failed to download file from all mirrors.
- Failed to download update file.
- Failed to download update manifest.
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/ed57da78a7964056.
Report an issue: GitHub.