microsoft/semantic-kernel · error · KernelException

Invalid response from model

Error message

Invalid response from model

What it means

Thrown by GeminiTokenCounterClient.DeserializeAndProcessCountTokensResponse when the deserialized JSON node's 'totalTokens' field is null or cannot be resolved as an integer. The count-tokens endpoint is expected to return { "totalTokens": <int> }; if that field is absent or has a non-integer value, this KernelException fires.

Source

Thrown at dotnet/src/Connectors/Connectors.Google/Core/Gemini/Clients/GeminiTokenCounterClient.cs:109

        string prompt,
        PromptExecutionSettings? executionSettings = null,
        CancellationToken cancellationToken = default)
    {
        Verify.NotNullOrWhiteSpace(prompt);

        var geminiRequest = CreateGeminiRequest(prompt, executionSettings);
        using var httpRequestMessage = await this.CreateHttpRequestAsync(geminiRequest, this._tokenCountingEndpoint).ConfigureAwait(false);

        string body = await this.SendRequestAndGetStringBodyAsync(httpRequestMessage, cancellationToken)
            .ConfigureAwait(false);

        return DeserializeAndProcessCountTokensResponse(body);
    }

    private static int DeserializeAndProcessCountTokensResponse(string body)
    {
        var node = DeserializeResponse<JsonNode>(body);
        return node["totalTokens"]?.GetValue<int>() ?? throw new KernelException("Invalid response from model");
    }

    private static GeminiRequest CreateGeminiRequest(
        string prompt,
        PromptExecutionSettings? promptExecutionSettings)
    {
        var geminiExecutionSettings = GeminiPromptExecutionSettings.FromExecutionSettings(promptExecutionSettings);
        ValidateMaxTokens(geminiExecutionSettings.MaxTokens);
        var geminiRequest = GeminiRequest.FromPromptAndExecutionSettings(prompt, geminiExecutionSettings);
        return geminiRequest;
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Catch KernelException around token-counting calls and fall back to an estimated token count (e.g. len/4 heuristic).
  2. Upgrade the Connectors.Google package to match the API version being used.
  3. Verify the model ID supports the count-tokens endpoint.
  4. Inspect the underlying HTTP response by enabling debug logging on the Google connector.

Example fix

try
{
    int count = await tokenCounter.CountTokensAsync(prompt, settings, ct);
}
catch (KernelException)
{
    // fallback estimate
    int estimatedCount = prompt.Length / 4;
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try
{
    tokenCount = await tokenCounter.CountTokensAsync(prompt, settings, ct);
}
catch (KernelException ex) when (ex.Message == "Invalid response from model")
{
    logger.LogWarning("Token counting failed, using estimate: {Estimate}", prompt.Length / 4);
    tokenCount = prompt.Length / 4; // rough heuristic
}

Prevention

When it happens

Trigger: Calling the Gemini token-counting endpoint (via CountTokensAsync or equivalent) and receiving a response that either lacks the totalTokens field, contains it as a non-integer (e.g. a string), or returns an error structure instead of the expected count payload.

Common situations: API version mismatch where the count-tokens response format changed. An error response (e.g. invalid model, auth failure) that was not caught as an HTTP error but partially parsed as JSON. Google changes the field name or structure in a newer API version.

Related errors


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