Gemini Interactions: HTTP 400 on continuation after streaming Google Search (v1 and v1beta)

# Gemini Interactions: HTTP 400 on continuation after streaming Google Search (v1 and v1beta)

## Summary

We observe a continuation failure with `gemini-3.8-flash` after an interaction that streams and actually executes the built-in `google_search` tool. The initial stream completes, but the next request using its `previous_interaction_id` fails with:

```text

contents[1].parts[0]: Tool type of tool_call part does not match with tool call context.

```

This occurs both when submitting a custom function result and when sending an ordinary follow-up user message with no custom function tools defined. It was reproduced using direct HTTP requests in Postman, independently of our application and without a Google SDK.

The controls below suggest an issue associated with continuation from an interaction created with streaming and Google Search. This is an observed pattern, not a confirmed diagnosis of the backend implementation.

## Environment

| Item | Value |

|—|—|

| Observation date | 1 October 2026 |

| Model | `gemini-3.8-flash` |

| API | Gemini Interactions API, direct REST |

| Host | `generativelanguage.googleapis.com` |

| Endpoints tested | `/v1/interactions` and `/v1beta/interactions` |

| Independent reproduction | Postman, HTTP POST; no SDK |

| Conversation state | `previous_interaction_id`; no manual history/signature replay |

| Thinking configuration | Failure with explicit `high` and with `generation_config` omitted |

The issue was initially observed in our MCM application (.NET Framework 4.7.2 / C# 7.3), then reproduced from fresh conversations in Postman. The initial requests below have no previous interaction ID. Prompts are retained in their tested Dutch wording to avoid introducing a translation as another variable.

## Expected versus actual behavior

**Expected:** after the initial interaction completes, a subsequent request with the returned interaction ID should continue the conversation. For a pending function call, a matching `function_result` should resume generation.

**Actual:** the continuation returns HTTP 400 with error code `invalid_request`. For a streaming continuation, the response body is:

```text

event: error

data: {“error”:{“message”:“contents[1].parts[0]: Tool type of tool_call part does not match with tool call context.”,“code”:“invalid_request”},“event_type”:“error”}

```

A non-streaming continuation from the same failing initial interaction returns the same message in a JSON error object. An earlier, longer tool sequence produced the same error with `contents[3].parts[0]`.

## Reproduction A — ordinary follow-up, no custom functions

Use the same API key for both requests. In Postman, use `POST`, Authorization `No Auth`, and Body `raw` / `JSON`.

```http

POST https://generativelanguage.googleapis.com/v1/interactions

Content-Type: application/json

x-goog-api-key: YOUR_API_KEY

```

### A1. Start a new streaming search interaction

```json

{

“model”: “gemini-3.8-flash”,

“stream”: true,

“tools”: [

{

  "type": "google_search"

}

],

“input”: “Gebruik Google Search om de noordelijkste stad van de Verenigde Staten te vinden. Gebruik daadwerkelijk de zoektool. Geef de naam van de stad, de staat en een bron.”

}

```

The prompt asks Google Search to find the northernmost city in the United States and return its name, state and a source.

Wait for the stream to finish. Verify that `google_search_call` and `google_search_result` actually occur and that `interaction.completed` reports `status: “completed”`. Copy `interaction.id` from that event. A run in which search is merely enabled but never executed is not a valid search reproduction.

### A2. Continue using an ordinary user message

Replace the placeholder with A1’s interaction ID. Use the same endpoint and headers.

```json

{

“model”: “gemini-3.8-flash”,

“stream”: true,

“previous_interaction_id”: “REPLACE_WITH_INTERACTION_ID_FROM_A1”,

“tools”: [

{

  "type": "google_search"

}

],

“input”: “Wat was de naam van de stad die je zojuist gevonden hebt? Antwoord uitsluitend met die naam. Gebruik geen nieuwe zoekopdracht.”

}

```

The follow-up asks only for the city name from the preceding answer, without a new search. The search tool remains in the tool list. This continuation produced the error above on `/v1/interactions`. No `function_call` or `function_result` is involved in this reproduction.

## Reproduction B — search followed by a custom function result

Start a separate fresh interaction. Use the same headers and endpoint as above.

### B1. Search and request a function

```json

{

“model”: “gemini-3.8-flash”,

“stream”: true,

“tools”: [

{

  "type": "google_search"

},

{

  "type": "function",

  "name": "get_weather",

  "description": "Retrieve weather information for a city.",

  "parameters": {

    "type": "object",

    "properties": {

      "city": {

        "type": "string"

      }

    },

    "required": \[

      "city"

    \]

  }

}

],

“input”: “Gebruik eerst Google Search om de noordelijkste stad van de Verenigde Staten te vinden. Roep daarna get_weather aan voor die stad. Gebruik voor het zoeken daadwerkelijk Google Search.”

}

```

Wait for the stream to finish. Verify:

1. `google_search_call` and `google_search_result` occur.

2. A `function_call` step requests `get_weather` (observed city: `Utqiagvik`).

3. `interaction.completed` has status `requires_action`.

Copy `interaction.id` and the `step.id` from the **get_weather function call**, not the Google Search call ID.

### B2. Submit the simulated result

Use the same endpoint. Replace both placeholders with the values from B1.

```json

{

“model”: “gemini-3.8-flash”,

“stream”: true,

“previous_interaction_id”: “REPLACE_WITH_INTERACTION_ID_FROM_B1”,

“tools”: [

{

  "type": "google_search"

},

{

  "type": "function",

  "name": "get_weather",

  "description": "Retrieve weather information for a city.",

  "parameters": {

    "type": "object",

    "properties": {

      "city": {

        "type": "string"

      }

    },

    "required": \[

      "city"

    \]

  }

}

],

“input”: [

{

  "type": "function_result",

  "name": "get_weather",

  "call_id": "REPLACE_WITH_GET_WEATHER_FUNCTION_CALL_ID",

  "result": \[

    {

      "type": "text",

      "text": "{\\"temperature_celsius\\":-5,\\"description\\":\\"Fictieve weergegevens voor deze technische test.\\"}"

    }

  \]

}

]

}

```

The weather result is intentionally fictitious test data; no real weather function needs to run. This continuation fails with the same context-mismatch error.

Repeat the complete B1/B2 sequence with `/v1beta/interactions` for **both** requests, using newly returned IDs. This also failed in our test. Reproduction A was tested on `/v1`; we have not established its result on `/v1beta`.

## Control tests

These are observed runs, not a statistical failure-rate measurement. Each initial search round in the comparisons executed Google Search.

| Endpoint | Initial request | Continuation | Thinking config | Continuation type | Result |

|—|—|—|—|—|—|

| v1beta | Non-streaming | Non-streaming | Omitted | Function result | Success |

| v1 | Non-streaming | Non-streaming | Omitted | Function result | Success |

| v1 | Non-streaming | Non-streaming | High | Function result | Success |

| v1 | Non-streaming | Streaming | High | Function result | Success |

| v1 | Streaming | Streaming | High | Function result | HTTP 400 |

| v1 | Streaming | Non-streaming | High | Function result | Same HTTP 400 |

| v1 | Streaming | Streaming | Omitted | Function result | Same HTTP 400 |

| v1beta | Streaming | Streaming | Omitted | Function result | Same HTTP 400 |

| v1 | Streaming | Streaming | Omitted | Ordinary user message | Same HTTP 400 |

For explicit High tests, both requests include:

```json

“generation_config”: { “thinking_level”: “high” }

```

The mixed-mode continuation controls reused the respective previously successful or failing initial interaction. They were not independent reruns of the entire conversation. Success means a response completed with the supplied tool result reflected in the answer; for streaming success, text deltas, `interaction.completed` with status `completed`, and `[DONE]` were observed.

Function-tool rounds without actual Google Search execution worked in our application tests. Omitting `generation_config` does not establish that thinking is disabled or that the effective default level differs from High.

## Checks and diagnostic evidence

- In the fully captured failing application run, the emitted interaction ID exactly matches the subsequent `previous_interaction_id`.

- The emitted function name and call ID match the submitted function result; arguments and simulated result were verified.

- The function-request interaction finishes with `requires_action` before its result is submitted.

- Tool definitions are unchanged between requests; explicit `thinking_level: “high”` is retained where configured.

- Fresh Postman runs reproduce the issue without our C# request builder, streaming parser or tool orchestration.

- Switching only the continuation from streaming to non-streaming does not repair a failing initial streaming-search interaction.

- A streaming continuation from a successful non-streaming-search interaction completes.

The full application SSE trace and Postman screenshots are available. Example timestamps from 1 October 2026 include `05:54:53Z` for the captured initial MCM search/function interaction, approximately `06:21:56Z–06:21:59Z` for the initial Postman streaming search/function control, and approximately `06:25:49Z–06:25:51Z` for the successful streaming continuation of a non-streaming interaction. API keys, opaque signatures and historical interaction IDs are omitted from this public report; fresh IDs must be used for reproduction. The ordinary-follow-up variant was recorded as a manual test with its returned error, rather than a full exported SSE trace.

## Impact and current mitigation

This prevents us from relying on stateful continuation after streaming Google Search, including ordinary user follow-ups and application tool-result rounds. We have decided to temporarily disable Gemini web search in MCM. This report does not claim that the application change has already been deployed.

Non-streaming search followed by continuation worked in the controls, but we have not validated it as a general workaround across multiple successive search/tool rounds or other models.

## Request to the Gemini API team

Could you investigate why continuation from these streaming Google Search interactions fails, while the non-streaming controls succeed? Please confirm whether this is a known issue or whether a request requirement is missing, and advise on a supported mitigation and fix status.

Relevant documentation:

- [Streaming interactions](https://ai.google.dev/gemini-api/docs/streaming)

- [Function calling and multi-tool use](https://ai.google.dev/gemini-api/docs/function-calling#multi-tool-use)

- [Combining built-in tools and function calling](https://ai.google.dev/gemini-api/docs/tool-combination)

The documented stateful path uses `previous_interaction_id` to maintain tool context. We are using that path rather than reconstructing search results or signatures manually.

I am also getting the 400 error with the Interactions API if I follow an Interaction that has used any tools, such as URL Context, Google Search, File Search. Files API seems to work if the file is still in the Files API and has not been deleted after 48 hours.

I first noticed the issue about a week ago when trying to continue a conversation with a text chat after a Nano Banana generation. I thought that was because it was image to text and I missed that in testing.

I have spent a couple of days getting values and tools from the previous interaction and injecting them into the next interaction, even if the user didn’t select those tools for the next interaction. But it still gives me a 400 error. I have had to fall back to the contentGeneration version as I can’t seem to get a fix.

My findings:

If I start a Nano Banana interaction chain, I can only continue that conversation with Nano Banana’s.

If I have a conversation chain with just the model and thinking mode level, I can continue that conversation.

If I add any tools such as Google Search, File Search, the interaction works, but any follow up interaction gives me a 400 error.

I still have Interaction chains from August which worked, so it seems something has happened between now and then.

Just to add to this, I have just done a test with the non streaming version and it seems to work correctly.

I have created the same interaction with google search, once with streaming and once without.

I checked the logs of both and noticed that the stream version is missing:
“search_type”: “web_search”

Non stream:

{

“id”: “call_150001”,

“type”: “google_search_call”,

“arguments”: {

“queries”: [

“weather in Leeds today”

]

},

“search_type”: “web_search”

}

Stream:

{

“id”: “call_88658”,

“type”: “google_search_call”,

“arguments”: {

"queries": \[

  "Leeds weather forecast today"

\]

}

}

Might be something to go on.

Thanks,

Elliot