Devolutions/UniGetUI · error · NullResponseException

Null response for request to

Error message

Null response for request to {url}

What it means

CratesIOClient.Fetch<T> throws NullResponseException when CargoJson.Deserialize<T> returns null. The HTTP status was already verified success (EnsureSuccessStatusCode), so a null here means the body parsed to JSON but could not map to T, or the body was 'null'.

Solutions

  1. Log the raw body for the failing URL when this fires to confirm the actual payload shape.
  2. Ensure CargoJson JsonSerializerContext includes T and that required members are present in the payload.
  3. Treat NullResponseException as a non-retryable data error for that id and degrade gracefully.

Example fix

// before
var data = CratesIOClient.Fetch<T>(url);
// after
T data;
try { data = CratesIOClient.Fetch<T>(url); }
catch (NullResponseException ex) { Logger.Warn(ex.Message); return default; }
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    return CratesIOClient.Fetch<T>(url);
}
catch (NullResponseException ex)
{
    Logger.Warn($"Crates.io returned null for {url}: {ex.Message}");
    return default;
}

Prevention

When it happens

Trigger: Any crates.io GET where the response is HTTP 200 but the JSON is 'null' or does not match the expected record shape T (missing required init members throw earlier, so null specifically means the deserializer returned null).

Common situations: Schema mismatch after a crates.io API change; an empty 200 body; a record type T with a custom converter that returns null.

Related errors


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

Appendix: source

Thrown at src/UniGetUI.PackageEngine.Managers.Cargo/CratesIOClient.cs:104

        }
        return manifest.version;
    }

    private static string GetApiUrl() => TEST_ApiUrlOverride ?? ApiUrl;

    internal static T Fetch<T>(Uri url)
    {
        using HttpClient client = new(CoreTools.GenericHttpClientParameters);
        client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString);
        using var request = new HttpRequestMessage(HttpMethod.Get, url);
        using HttpResponseMessage response = client.Send(request);
        response.EnsureSuccessStatusCode();

        string manifestStr = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

        var manifest =
            CargoJson.Deserialize<T>(manifestStr)
            ?? throw new NullResponseException($"Null response for request to {url}");
        return manifest;
    }
}

public class NullResponseException(string message) : Exception(message);

View on GitHub (pinned to 9b1d7d0eab)