# Nano Banana 2 Thought Signature Error: Fix the Second-Turn 400

> Nano Banana 2 returns 400 when a follow-up edit resends its earlier image without the thought signature. Use previous_interaction_id or SDK chat history.

- URL: https://blog.laozhang.ai/en/posts/nano-banana-2-thought-signature-error
- Published: 2026-03-09
- Updated: 2026-10-05
- Author: LaoZhang AI Team (https://blog.laozhang.ai/en/about)
- Topic: Troubleshooting
- Tags: Nano Banana 2, Thought Signature, Gemini API, API Error Fix

---
The error usually looks like this:

```text
400 INVALID_ARGUMENT: Image part is missing a thought_signature in content position 2, part position 1.
```

It means your second request sent back the image Nano Banana 2 made in the first turn, but without the encrypted thought signature that came attached to it. The first request works; every follow-up edit fails. That is why it so often shows up in frameworks that rebuild chat history from plain text and image messages.

There are three documented ways out, in this order:

1. **Let Google keep the state.** Use the Interactions API and pass `previous_interaction_id` on the next turn. Google's own image-editing examples work this way, and the server handles signatures for you.
2. **Send the model's turn back unchanged.** With `generateContent`, use the SDK chat object or append `response.candidates[0].content` to your history as-is.
3. **Update or patch the framework.** Vercel AI SDK fixed image signatures in `ai` 6.0.114. For other tools, check their issue tracker or send each edit as a fresh single-turn request.

Use the current model IDs: `gemini-3.1-flash-image` for Nano Banana 2 and `gemini-3-pro-image` for Nano Banana Pro. The `-preview` versions of both were shut down on June 25, 2026 ([Gemini API deprecations](https://ai.google.dev/gemini-api/docs/deprecations)). The code below follows Google's documented request shapes but hasn't been run for this page.

## What "missing a thought_signature" means

A thought signature is, in Google's words, an encrypted representation of the model's internal reasoning, "required to maintain reasoning continuity across multi-turn interactions" ([Gemini thinking guide](https://ai.google.dev/gemini-api/docs/thinking), as of October 5, 2026). You can't read it or edit it. You can only return it exactly as you received it.

Where it lives depends on the API:

| API | Where signatures appear | What you have to do |
| --- | --- | --- |
| Interactions, stateful (`previous_interaction_id`) | Stored on Google's side | Nothing |
| Interactions, stateless (you send the full history) | Dedicated thought steps and built-in tool steps such as `google_search` | Resend every thought step exactly as received |
| `generateContent` | A `thoughtSignature` field on a content part: an image part, a `functionCall` part, or the last part of a reply | Resend the model's parts unchanged, signature included |

The same failure has three names depending on where you see it. With `generateContent` it arrives as HTTP 400 `INVALID_ARGUMENT` with a message like the one above, and the API reference also lists a finish reason `MISSING_THOUGHT_SIGNATURE` ("Request has at least one thought signature missing"). The Interactions API lists the error code `missing_thought_signature` ([Gemini API errors](https://ai.google.dev/gemini-api/docs/api-errors)).

The positions in the message point at what was lost. In the Vercel AI SDK report, the history was user prompt, model image, new user prompt, so "content position 2, part position 1" was the image the model had just generated ([vercel/ai #12988](https://github.com/vercel/ai/issues/12988)). Check that turn first.

Turning thinking down doesn't remove the requirement. Google Cloud's documentation says Gemini 3 models need signatures returned "even when using MINIMAL thinking levels" ([Thought signatures, Google Cloud](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/thinking/thought-signatures)).

## Why it breaks on Nano Banana 2 when the same code worked before

Google Cloud's documentation says Gemini 3 models enforce stricter signature validation and return 400 when a required signature is missing. It makes one explicit exception: Gemini 3 Pro Image "doesn't return a 400 error if a thought signature isn't returned," although you should still send signatures back for best results. Don't lean on that exemption, though: a [Dify plugin report from December 2025](https://github.com/langgenius/dify-official-plugins/issues/2262) shows the same "Image part is missing a thought_signature" 400 on the Nano Banana Pro preview.

Nano Banana 2 behaves differently in practice. In the Vercel AI SDK report, a second turn after Nano Banana 2 generated an image failed with the error above, while the reporter noted that "this flow already works fine with gemini-2.5-flash-image." The fix landed in `ai` 6.0.114 as "fix missing support for image thought signatures."

So code that silently dropped signatures could run for months against Nano Banana Pro or the first Nano Banana, then fail the moment you switch to Nano Banana 2. That switch is no longer optional for many projects: `gemini-2.5-flash-image` was shut down on October 2, 2026.

The usual ways a signature gets lost:

- The framework stores only text and image bytes, then rebuilds the model turn from them.
- Your code decodes the image, saves it, and later re-wraps it as a new image part.
- A history-trimming step merges or reorders parts. Google warns against merging a signed part with an unsigned one or combining two signed parts, because the signature depends on its position.
- A streaming handler skips a chunk that carried the signature (see the streaming section below).

## Fix 1: keep state on the server with previous_interaction_id

If you're starting fresh or can change how you call the API, this is the simplest route. In the Interactions API's stateful mode (`store: true` plus `previous_interaction_id` on later turns), "you do not need to do anything regarding signatures. They are handled entirely on the server side" ([Gemini thinking guide](https://ai.google.dev/gemini-api/docs/thinking)). Google's [image generation guide](https://ai.google.dev/gemini-api/docs/image-generation) uses the same pattern for multi-turn edits.

```python
# Untested sketch; request shapes follow Google's image generation guide.
import base64
from google import genai

client = genai.Client()  # reads GEMINI_API_KEY

first = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="A white ceramic mug on a wooden desk, soft morning light",
)

second = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="Make the mug matte black. Keep everything else unchanged.",
    previous_interaction_id=first.id,
)

if second.output_image:
    with open("mug-v2.png", "wb") as f:
        f.write(base64.b64decode(second.output_image.data))
```

Keep only `first.id` between turns, not the image. Google's sample doesn't pass `store` explicitly. If your code sets it to false, you're in stateless mode and must resend every thought step yourself.

Custom safety settings aren't available in the Interactions API. If you depend on them, use Fix 2.

## Fix 2: return the model's parts unchanged in generateContent

With `generateContent`, the official Google Gen AI SDKs handle signatures automatically when you use chat history or append the full model response to your next request. Google Cloud's multi-turn image-editing example uses the chat object.

The chat version:

```python
# Untested sketch.
from google import genai
from google.genai import types

client = genai.Client()
config = types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"])

chat = client.chats.create(model="gemini-3.1-flash-image", config=config)
chat.send_message("A white ceramic mug on a wooden desk, soft morning light")
reply = chat.send_message("Make the mug matte black. Keep everything else unchanged.")

for part in reply.candidates[0].content.parts:
    if part.inline_data:
        with open("mug-v2.png", "wb") as f:
            f.write(part.inline_data.data)
```

If you manage history yourself, append the model's `Content` object rather than rebuilding it:

```python
# Untested sketch.
history = [types.Content(role="user", parts=[types.Part(text="A white ceramic mug on a wooden desk")])]
first = client.models.generate_content(model="gemini-3.1-flash-image", contents=history, config=config)

history.append(first.candidates[0].content)  # every part, signatures included
history.append(types.Content(role="user", parts=[types.Part(text="Make the mug matte black.")]))
second = client.models.generate_content(model="gemini-3.1-flash-image", contents=history, config=config)
```

What breaks it is rebuilding the turn by hand, for example `types.Content(role="model", parts=[types.Part.from_bytes(data=image_bytes, mime_type="image/png")])`. The pixels survive, but the signature doesn't.

Over REST, copy the model turn from the response into the next request's `contents` without touching it. A part carrying a signature has this shape:

```json
{
  "role": "model",
  "parts": [
    {
      "inlineData": { "mimeType": "image/png", "data": "BASE64_IMAGE_FROM_RESPONSE" },
      "thoughtSignature": "SIGNATURE_FROM_RESPONSE"
    }
  ]
}
```

To resume a conversation later, save the whole model turn (every part with its `thoughtSignature`), not just the decoded image file.

## Fix 3: Vercel AI SDK, Dify and n8n need a framework-side fix

When the history is built by a tool you don't control, your own code can't add the signature back in. You have three practical options.

**Update the framework.** For the Vercel AI SDK, upgrade the `ai` package to 6.0.114 or later, where image thought signatures were fixed ([vercel/ai #12988](https://github.com/vercel/ai/issues/12988)).

**Check the issue tracker.** There are developer reports of the same second-turn failure in the Dify official plugins repository (Nano Banana Pro failing on a second image) and in the n8n community forum ("Gemini Pro 3 - Thought Signature Error"). Whether a release has fixed them depends on your plugin or node version. Look for the fix version in the thread before upgrading, and if there isn't one, file an issue with the exact error text and model ID.

**Edit in single turns instead.** Send the latest image as an input image in a new request together with the edit instruction. Signatures belong to the model's own turns, so a request whose history contains no model turn has nothing to validate. The trade-off is that each request starts without the reasoning from earlier turns. Use this as a stopgap until the framework passes signatures through.

OpenAI-compatible endpoints are their own case. Google Cloud's documentation shows function-call signatures carried in `extra_content.google.thought_signature` on Chat Completions `tool_calls`. There is no equivalent documented field for image parts, so for multi-turn image editing, call the native API.

## Function calls and agents: which Gemini 3 signatures are validated

If your Nano Banana 2 flow sits inside an agent that also calls tools, the function-calling rules apply too. They come from Google Cloud's thought signatures page and cover Gemini 3 models:

- **Sequential calls:** each step's `functionCall` part carries a signature. Within the current turn, leaving out the signature on the first `functionCall` part of any step returns 400. A turn starts at the latest user message that isn't a `functionResponse`.
- **Parallel calls:** only the first `functionCall` part carries the signature. Send back all calls first, then all responses (FC1 with its signature, FC2, FR1, FR2). Interleaving them (FC1, FR1, FC2, FR2) returns 400.
- **Replies without a function call:** a signature may sit on the last part. Returning it is recommended, and leaving it out doesn't raise an error for text-only replies.

Images are the exception to that last rule on Nano Banana 2, at least in developer reports. A model-generated image part that comes back without its signature is what triggers the "Image part is missing" error.

![Thought signature handling across follow-up image edits, sequential and parallel function calls, and text replies](https://blog.laozhang.ai/posts/en/nano-banana-2-thought-signature-error/img/content-1.webp)

## skip_thought_signature_validator: last resort, function calls only

Google documents one escape hatch: setting `thought_signature` to `skip_thought_signature_validator`. It applies to `functionCall` parts the API didn't generate, for example history migrated from a model that doesn't produce signatures. Google calls it "a last resort as it will negatively impact model performance."

It is not documented for image parts. An image the model generated in an earlier turn has a real signature, so the fix is to keep that signature, not to replace it. Placeholder strings for image parts that circulate in older posts have no support in Google's current documentation.

## Streaming and model switches: keep every part until finish_reason

When streaming, Google Cloud notes that a signature "might be returned in a part with empty text content, so be sure to parse all parts until finish_reason is returned." A handler that only keeps chunks with non-empty `text` throws that part away. Collect every part of every chunk, and with the SDK, prefer its own accumulation over stitching text yourself. In the Interactions API, the `thought_signature` delta is the last delta before `step.stop`.

![Illustrative streaming sequence showing why all parts and their signatures must be kept in order](https://blog.laozhang.ai/posts/en/nano-banana-2-thought-signature-error/img/content-2.webp)



If you switch models mid-conversation, for example from Nano Banana Pro to Nano Banana 2, keep resending the earlier model's signed turns. Google's thinking guide says the backend manages compatibility when you send the previous model's thought blocks.

## Errors that look similar but aren't thought signatures

- **"Something went wrong" in the Gemini app.** This is an app-side failure, not an API error, so none of the fixes above apply. See [Nano Banana Not Working in Gemini? Fix Stuck or Missing Images](https://blog.laozhang.ai/en/posts/nano-banana-not-working-gemini-image-errors), or [Nano Banana Pro Error 5: 3 Checks for Something Went Wrong (5)](https://blog.laozhang.ai/en/posts/nano-banana-pro-error-5) for the numbered variant.
- **200 OK with no image.** The request succeeded but returned text or a finish reason instead of an image. See [Nano Banana API Returns No Image? Find the Cause in the Response](https://blog.laozhang.ai/en/posts/nano-banana-2-200-ok-no-image).
- **429, 503, safety blocks and parameter errors** have different causes and fixes. Start from [the Gemini image error guide](https://blog.laozhang.ai/en/posts/gemini-image-common-errors-fix). For request setup and current model IDs, see [Gemini Image API Guide: Python Code, 3 Current Models, Pricing](https://blog.laozhang.ai/en/posts/gemini-image-api-guide-2026).

## FAQ

### Does Nano Banana Pro need thought signatures in multi-turn edits?

Google says Gemini 3 Pro Image doesn't return 400 when a signature is missing, but you should still send signatures back so the model keeps its context. Handle them the same way for both models, and code written for Pro will keep working when you switch to Nano Banana 2.

### Can I store thought signatures and resume an image edit later?

Yes. Save the complete model turn, with every part and its `thoughtSignature`, and send it back unchanged when the user returns. With the Interactions API, saving the interaction ID and passing it as `previous_interaction_id` is enough.

### Can I fake a thought signature for a Nano Banana 2 image part?

No documented method exists. The only bypass Google describes, `skip_thought_signature_validator`, covers `functionCall` parts the API didn't generate, and Google says it degrades performance. For images, keep the real signature or start a fresh single-turn edit.

## Official documentation

Request parameters, pricing, and billing rules are documented in the LaoZhang API developer docs: [Image billing and failures](https://docs.laozhang.ai/en/api-capabilities/image-billing-and-failures).

*Disclosure: [laozhang.ai is our own service](https://blog.laozhang.ai/en/about#laozhang). Its prices are platform pricing, not an independent comparison.*

## Sources

External pages this guide links to, in the order they appear. Last updated 2026-10-05.

- [Gemini API deprecations](https://ai.google.dev/gemini-api/docs/deprecations) (ai.google.dev)
- [Gemini thinking guide](https://ai.google.dev/gemini-api/docs/thinking) (ai.google.dev)
- [Gemini API errors](https://ai.google.dev/gemini-api/docs/api-errors) (ai.google.dev)
- [vercel/ai #12988](https://github.com/vercel/ai/issues/12988) (github.com)
- [Thought signatures, Google Cloud](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/thinking/thought-signatures) (docs.cloud.google.com)
- [Dify plugin report from December 2025](https://github.com/langgenius/dify-official-plugins/issues/2262) (github.com)
- [image generation guide](https://ai.google.dev/gemini-api/docs/image-generation) (ai.google.dev)
