microsoft/semantic-kernel · error · Exception

Response is not available.

Error message

Response is not available.

What it means

EvaluationService.EvaluateAsync POSTs an evaluation request to an HTTP evaluation server, reads the JSON response body, and uses System.Text.Json to deserialize it into the expected TResponse. If JsonSerializer.Deserialize returns null (the response body was the literal JSON token 'null', or the root value couldn't be deserialized), it throws a generic Exception. Note: a malformed JSON would throw JsonException earlier, so this specific throw only fires on a valid-but-null root.

Source

Thrown at dotnet/samples/Demos/QualityCheck/QualityCheckWithFilters/Services/EvaluationService.cs:26

/// <summary>
/// Service which performs HTTP requests to evaluation server.
/// </summary>
internal sealed class EvaluationService(HttpClient httpClient, string endpoint)
{
    public async Task<TResponse> EvaluateAsync<TRequest, TResponse>(TRequest request)
        where TRequest : EvaluationRequest
    {
        var requestContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");

        var response = await httpClient.PostAsync(new Uri(endpoint, UriKind.Relative), requestContent);

        response.EnsureSuccessStatusCode();

        var responseContent = await response.Content.ReadAsStringAsync();

        return JsonSerializer.Deserialize<TResponse>(responseContent) ??
            throw new Exception("Response is not available.");
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect the raw responseContent before deserializing — log it or add a check for null/empty strings.
  2. Verify the evaluation server endpoint path and expected response schema match the TResponse type.
  3. Handle the case where the server legitimately returns null (empty input) by returning a default or throwing a more descriptive exception.
  4. Use JsonSerializerOptions with error handling or deserialize into JsonElement first to inspect the structure.

Example fix

// before
return JsonSerializer.Deserialize<TResponse>(responseContent) ??
    throw new Exception("Response is not available.");

// after — surface the raw body in the error for debugging
var result = JsonSerializer.Deserialize<TResponse>(responseContent);
if (result is null)
    throw new InvalidOperationException(
        $"Evaluation server returned a null response. Raw body: {responseContent}");
return result;
Defensive patterns

Strategy: validation

Validate before calling

// Inspect raw response before deserializing
var responseContent = await response.Content.ReadAsStringAsync();
if (string.IsNullOrWhiteSpace(responseContent) || responseContent.Trim() == "null")
    throw new InvalidOperationException($"Evaluation server returned null/empty body. Status: {response.StatusCode}");

Try / catch

try { return await evaluationService.EvaluateAsync<TReq, TResp>(request); } catch (Exception ex) { logger.LogError(ex, "Evaluation deserialization failed for {Endpoint}", endpoint); throw; }

Prevention

When it happens

Trigger: The evaluation server responds with HTTP 200 and a body of 'null', or the response JSON root deserializes to null for the target type (e.g., a nullable reference whose value is absent and the type doesn't initialize it). This is distinct from a network error (HttpRequestException from PostAsync) or a non-2xx status (HttpRequestException from EnsureSuccessStatusCode).

Common situations: The evaluation server returns null when it has no score to compute (e.g., empty input); the server's API contract changed and now returns a wrapper object instead of the raw type; a proxy or gateway injected a null response; the endpoint path is wrong and the server returns null instead of an error.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/ba0039d2f3e73c17. Report an issue: GitHub.