Devolutions/UniGetUI · error · NullResponseException

Null response for request to {url}

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'.

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)

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.