micro/go-micro · error

gemini stream error (%s): %s

Error message

gemini stream error (%s): %s

What it means

The Gemini stream delivered a chunk whose top-level "error" field was set, meaning the API itself reported a mid-stream failure (e.g. quota exceeded, invalid API key, model error). The library surfaces it as 'gemini stream error (<status>): <message>' with the provider's status and message verbatim. The request reached the API and was accepted at transport level, then failed server-side.

Source

Thrown at ai/gemini/gemini.go:249

			} `json:"error"`
			Candidates []struct {
				Content struct {
					Parts []struct {
						Text string `json:"text"`
					} `json:"parts"`
				} `json:"content"`
			} `json:"candidates"`
			UsageMetadata *struct {
				PromptTokenCount     int `json:"promptTokenCount"`
				CandidatesTokenCount int `json:"candidatesTokenCount"`
				TotalTokenCount      int `json:"totalTokenCount"`
			} `json:"usageMetadata"`
		}
		if err := json.Unmarshal([]byte(data), &chunk); err != nil {
			return nil, fmt.Errorf("failed to parse stream chunk: %w", err)
		}
		if chunk.Error != nil {
			return nil, fmt.Errorf("gemini stream error (%s): %s", chunk.Error.Status, chunk.Error.Message)
		}
		for _, candidate := range chunk.Candidates {
			var parts []string
			for _, part := range candidate.Content.Parts {
				if part.Text != "" {
					parts = append(parts, part.Text)
				}
			}
			if len(parts) > 0 {
				return &ai.Response{Reply: strings.Join(parts, "")}, nil
			}
		}
		if chunk.UsageMetadata != nil {
			return &ai.Response{Usage: ai.Usage{
				InputTokens:  chunk.UsageMetadata.PromptTokenCount,
				OutputTokens: chunk.UsageMetadata.CandidatesTokenCount,
				TotalTokens:  chunk.UsageMetadata.TotalTokenCount,
			}}, nil

View on GitHub (pinned to 24529f1404)

Solutions

  1. Parse the status code in the message: RESOURCE_EXHAUSTED → check quota/billing; UNAUTHENTICATED → fix API key; INVALID_ARGUMENT → fix request params.
  2. Verify x-goog-api-key corresponds to a valid, enabled key with Generative Language API access.
  3. If quota-related, enable billing on the Google Cloud project or add client-side rate limiting/backoff.
  4. Retry after the delay suggested in the message for transient capacity errors.

Example fix

// before
chunk, err := stream.Recv(ctx)
if err != nil { return err }
// after
chunk, err := stream.Recv(ctx)
if err != nil {
    var quotaErr *QuotaExceededError
    if strings.Contains(err.Error(), "RESOURCE_EXHAUSTED") && errors.As(err, &quotaErr) {
        time.Sleep(quotaErr.RetryAfter)
        chunk, err = stream.Recv(ctx)
    }
    if err != nil { return err }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if apiKey == "" || !strings.HasPrefix(apiKey, "AI") {
    return errors.New("GEMINI API key missing or malformed")
}
// also pre-check model name against supported list

Type guard

type GeminiStreamError struct{ Status, Message string }
func asGeminiStreamError(err error) (status, msg string, ok bool) {
    if err == nil { return "", "", false }
    const p = "gemini stream error ("
    i := strings.Index(err.Error(), p)
    if i < 0 { return "", "", false }
    rest := err.Error()[i+len(p):]
    j := strings.Index(rest, "): ")
    if j < 0 { return "", "", false }
    return rest[:j], rest[j+3:], true
}

Try / catch

text, err := stream.Recv(ctx)
if err != nil {
    if status, msg, ok := asGeminiStreamError(err); ok {
        switch status {
        case "RESOURCE_EXHAUSTED":
            return backoffAndRetry(ctx, req)
        case "UNAUTHENTICATED":
            return fmt.Errorf("check GEMINI API key: %s", msg)
        default:
            return fmt.Errorf("gemini %s: %s", status, msg)
        }
    }
    return err
}

Prevention

When it happens

Trigger: Recv on a stream where Gemini emitted {"error": {"status": ..., "message": ...}} — typically RESOURCE_EXHAUSTED, UNAUTHENTICATED (bad x-goog-api-key), INVALID_ARGUMENT, or model unavailability.

Common situations: Expired/incorrect GEMINI API key; exhausted free-tier quota or rate limit; invalid model name passed request-stage validation; prompts exceeding context limits; regional availability issues.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/4f9bfafde4b8e73e. Report an issue: GitHub.