UsageMetadata is nil in GenerateContentStream final response for gemini-2.5-pro-preview, works for gemini-2.0-flash

Hi everyone,

I’m using the “genai package - google.golang.org/genai - Go Packages” SDK to stream responses from Gemini models. I’m calling the GenerateContentStream function. I iterate over this sequence using a for range loop.

My goal is to retrieve the token usage information from the UsageMetadata field of the last successfully received genai.GenerateContentResponse object after the stream (and the loop) finishes normally.

But I cannot get the UsageMetadata for gemini-1.5-pro-preview, but it works for gemini-1.5-flash.

Here’s the relevant structure of my code:

// Assume ctx, gp.client, gp.logger, contentParts, config, outChan are defined
// modelName is set to either “models/gemini-1.5-pro-preview-xxxx” or “models/gemini-1.5-flash-xxxx”

iter := gp.client.Models.GenerateContentStream(ctx, modelName, contentParts, config)

var finalResponse *genai.GenerateContentResponse // To store the last valid response

// — Process Stream —
for resp, err := range iter {
if err != nil { // Handle errors
gp.logger.Error(fmt.Sprintf(“Error reading Gemini stream: %v”, err), err)
outChan ← StreamChunk{Err: fmt.Errorf(“stream read error: %w”, err)}
// Cannot reliably get usage on error
return &UsageInfo{}, err
}

// Process valid response chunk (err is nil here)
finalResponse = resp // Store the latest response

// --- Extract text delta and send to channel ---
var deltaText string
if len(resp.Candidates) > 0 && resp.Candidates[0].Content != nil {
    for _, part := range resp.Candidates[0].Content.Parts {
        // Consider handling other part types besides genai.Text if necessary
        if textPart, ok := part.(genai.Text); ok {
             deltaText += string(textPart)
        }
    }
}
if deltaText != "" {
    outChan <- StreamChunk{Delta: deltaText}
}
// --- End of delta extraction ---

}

// — After the loop finishes normally —
// Attempt to get usage info from the finalResponse
if finalResponse != nil && finalResponse.UsageMetadata != nil {
// Successfully accessed UsageMetadata
promptTokens := finalResponse.UsageMetadata.PromptTokenCount
candidateTokens := finalResponse.UsageMetadata.CandidatesTokenCount
gp.logger.Info(fmt.Sprintf(“UsageMetadata found: Prompt=%d, Candidates=%d”, promptTokens, candidateTokens))
// … process usageInfo …
} else {
// Failed to access UsageMetadata
if finalResponse == nil {
gp.logger.Warning(“Stream loop finished, but finalResponse is nil.”)
} else {
// *** This is the problem point for gemini-1.5-pro-preview ***
gp.logger.Warning(“Stream loop finished, finalResponse exists, but finalResponse.UsageMetadata is nil.”)
}
// … handle missing usageInfo …
}

// usageInfo := convertGeminiUsage(finalResponse) // If using a helper function