Skip to content

Bug: Gemini Context Caching Conflicts with systemInstruction and tools (PR #71441 closed without merge) #84919

@rafaelmariano-glitch

Description

@rafaelmariano-glitch

Bug: Gemini Context Caching Conflicts with systemInstruction and tools

Problem

When cacheRetention: "long" is configured for a Gemini model with tools, the OpenClaw gateway sends cachedContent, systemInstruction, AND tools/toolConfig in the same request. The Google Gemini API rejects this combination with error 400:

Google Generative AI API error (400): CachedContent can not be used with GenerateContent request setting system_instruction, tools or tool_config.

Root Cause

The code in transport-stream-DyvRcab3.js (function buildGoogleGenerativeAiParams) sends all fields unconditionally:

if (typeof options?.cachedContent === "string" && options.cachedContent.trim()) 
    params.cachedContent = options.cachedContent.trim();
if (context.systemPrompt) 
    params.systemInstruction = { parts: [{ text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt)) }] };
if (context.tools?.length) {
    params.tools = convertGoogleTools(context.tools);
    const toolChoice = mapToolChoice(options?.toolChoice);
    if (toolChoice) params.toolConfig = { functionCallingConfig: toolChoice };
}

According to Google's API documentation, when cachedContent is used, the systemInstruction, tools, and toolConfig must NOT be sent separately — they should already be embedded in the cached content.

Previous Work

PR #71441 implemented the correct fix:

This means the fix exists but was never applied to the codebase.

Impact

Workaround: Remove cacheRetention from all Gemini model configs:

{
  "google/gemini-3.5-flash": {}  // no cacheRetention
}

Cost Impact: Without context caching, users pay 100% of input token costs instead of ~25% (cache read rate). For agents with large system prompts (~35KB), this represents significant cost overhead.

Reproduction

  1. Configure a Gemini model with cacheRetention: "long" and tools
  2. Create an agent with a large system prompt (SOUL.md, TOOLS.md, etc.)
  3. Send a message to the agent
  4. Observe error 400 from Google API

Environment

  • OpenClaw version: 2026.5.19 (a185ca2)
  • Model: google/gemini-3.5-flash (also affects gemini-3.1-flash-lite, gemini-2.5-flash-lite, gemini-2.0-flash)
  • Config: cacheRetention: "long" + agent with tools

Related

Suggested Fix

Re-open and merge PR #71441, or apply equivalent fix:

const usesCachedContent = typeof options?.cachedContent === "string" && options.cachedContent.trim();
if (usesCachedContent) params.cachedContent = options.cachedContent.trim();
if (!usesCachedContent && context.systemPrompt) 
    params.systemInstruction = { parts: [{ text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt)) }] };
if (!usesCachedContent && context.tools?.length) {
    params.tools = convertGoogleTools(context.tools);
    const toolChoice = mapToolChoice(options?.toolChoice);
    if (toolChoice) params.toolConfig = { functionCallingConfig: toolChoice };
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions