Repository navigation
Description
Interactions API: previous_interaction_id chain re-roots mid-conversation, then rejects a valid function_result
Model: gemini-3.8-flash · Endpoint: POST /v1beta/interactions (streaming) · SDK: google-genai 2.8.0 and 2.25.0 (same result) · Reproduced: 2026-09-22
Summary
In a tool-calling conversation chained only with previous_interaction_id, the server
sometimes starts a new conversation root partway through. Two interactions later,
answering the pending function_call with a function_result fails with:
invalid_request: Please ensure that function response turn comes immediately after a function call turn. Got function response with name 'run_travel_code'.
The client's request is valid. The interaction being chained off ends in a function_call,
and the function_result answers that call's id.
How the re-root shows up
An interaction id is v1_<urlsafe base64 protobuf>: field 1 is the conversation root id and
field 2 is the interaction's own id. They should be equal only on a conversation's first
interaction. In failing runs they become equal mid-chain (RE-ROOTED below). The
rejection follows two interactions later, when the rebuilt history seems to start with a
function_result whose function_call belongs to the old root.
Evidence it is server-side
Checked against the rejected interaction:
- Its stored steps are
function_result -> thought -> function_call, so answering it is legal. - Replaying the identical request is rejected every time; it isn't transient.
- Plain-text input chained to the same interaction is accepted.
- The same history flattened from
interactions.getand sent explicitly, without
previous_interaction_id, is accepted. Same content, so only the server-side chain
reconstruction is wrong.
Not caused by the SDK: reproduces on 2.8.0 and 2.25.0, and toggling the api-revision
header 2.8.0 sends makes no difference. Not caused by timing: reproduces with no delay
between turns. It happens in roughly 10-50% of conversations, varying from run to run.
Repro
Attached gemini_reroot_repro.py (self-contained; needs GEMINI_API_KEY):
uv run gemini_reroot_repro.py
It exits 1 when it catches the bug. Each run may not catch it; re-run or pass --conversations 16.
Example run
Excerpt: conversations that hit the bug are shown in full; 8 clean and 2 re-rooted without a rejection omitted. The full log is attached as gemini_reroot_bug_report.log.
==============================================================================
Gemini Interactions API -- conversation re-root breaks previous_interaction_id
==============================================================================
google-genai : 2.25.0
python : 3.13.11
model : gemini-3.8-flash
started (UTC): 2026-09-22T19:43:36Z
An interaction id is v1_<base64 protobuf>: field 1 is the conversation ROOT id, field 2
is the interaction's OWN id. They should match only on a conversation's first turn.
Running 12 conversations concurrently; each prints its table when it
finishes. >> = re-rooted (root == self mid-chain) XX = function_result rejected
Conversation 11 -- HIT THE BUG
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
-----------------------------------------------------------------------------------------------------------------------
1 start 1 aNqyapjKNdW7qtsPq9nq4QU aNqyapjKNdW7qtsPq9nq4QU (none) v1_ChdhTnF5YXBqS05kVzdxdHNQcTlucTRRVRIXYU5xeWFwaktOZFc3cXRzUHE5bnE0UVU
>> 2 RE-ROOTED 1 a9qyaqDwEYjsz7IPiY2foQU a9qyaqDwEYjsz7IPiY2foQU aNqyapjKNdW7qtsPq9nq4QU v1_ChdhOXF5YXFEd0VZanN6N0lQaVkyZm9RVRIXYTlxeWFxRHdFWWpzejdJUGlZMmZvUVU
3 ok 1 a9qyaqDwEYjsz7IPiY2foQU bdqyasjfIfeHqtsPo5LB-Qk a9qyaqDwEYjsz7IPiY2foQU v1_ChdhOXF5YXFEd0VZanN6N0lQaVkyZm9RVRIXYmRxeWFzamZJZmVIcXRzUG81TEItUWs
XX 4 REJECTED - - - bdqyasjfIfeHqtsPo5LB-Qk (rejected - no interaction created)
>> RE-ROOTED at turn 2: root (field 1) became the interaction's own id, so the server started a new conversation root mid-chain.
XX REJECTED at turn 4: submitting the function_result chained off the previous interaction failed with:
Please ensure that function response turn comes immediately after a function call turn. Got function response with name 'run_travel_code'.
Conversation 6 -- HIT THE BUG
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
-----------------------------------------------------------------------------------------------------------------------
1 start 1 adqyavisAbTmz7IPqLPtqQQ adqyavisAbTmz7IPqLPtqQQ (none) v1_ChdhZHF5YXZpc0FiVG16N0lQcUxQdHFRURIXYWRxeWF2aXNBYlRtejdJUHFMUHRxUVE
2 ok 1 adqyavisAbTmz7IPqLPtqQQ atqyaovUOMGoqtsPp9-n8A0 adqyavisAbTmz7IPqLPtqQQ v1_ChdhZHF5YXZpc0FiVG16N0lQcUxQdHFRURIXYXRxeWFvdlVPTUdvcXRzUHA5LW44QTA
3 ok 1 adqyavisAbTmz7IPqLPtqQQ bdqyauPqAZOxqtsPo_6E6A0 atqyaovUOMGoqtsPp9-n8A0 v1_ChdhZHF5YXZpc0FiVG16N0lQcUxQdHFRURIXYmRxeWF1UHFBWk94cXRzUG9fNkU2QTA
>> 4 RE-ROOTED 1 cNqyata5JY6sz7IP8K7uoAg cNqyata5JY6sz7IP8K7uoAg bdqyauPqAZOxqtsPo_6E6A0 v1_ChdjTnF5YXRhNUpZNnN6N0lQOEs3dW9BZxIXY05xeWF0YTVKWTZzejdJUDhLN3VvQWc
5 ok 1 cNqyata5JY6sz7IP8K7uoAg dNqyauqgPOzzz7IP5Z2x4AQ cNqyata5JY6sz7IP8K7uoAg v1_ChdjTnF5YXRhNUpZNnN6N0lQOEs3dW9BZxIXZE5xeWF1cWdQT3p6ejdJUDVaMng0QVE
XX 6 REJECTED - - - dNqyauqgPOzzz7IP5Z2x4AQ (rejected - no interaction created)
>> RE-ROOTED at turn 4: root (field 1) became the interaction's own id, so the server started a new conversation root mid-chain.
XX REJECTED at turn 6: submitting the function_result chained off the previous interaction failed with:
Please ensure that function response turn comes immediately after a function call turn. Got function response with name 'run_travel_code'.
==============================================================================
re-rooted mid-chain : 4/12
rejected submissions: 2/12
==============================================================================
Controls against the rejected interaction
v1_ChdjTnF5YXRhNUpZNnN6N0lQOEs3dW9BZxIXZE5xeWF1cWdQT3p6ejdJUDVaMng0QVE
[0] its stored steps: function_result -> thought -> function_call
it ends in a function_call, so answering with a function_result is legal
[1.1] replay of the rejected request: rejected again
[1.2] replay of the rejected request: rejected again
[2] same interaction with PLAIN TEXT input: accepted
[3] SAME history sent EXPLICITLY (15 steps, no previous_interaction_id): ACCEPTED
=> the content is valid; only the server's chain reconstruction is wrong
Activity
Venkaiahbabuneelam commentedon Sep 23, 2026
Hi @JasonSteving99,
Thank you for providing such a detailed bug report, logs, and the self-contained reproduction script (gemini_reroot_repro.py). I ran the reproduction script across multiple test runs with concurrent multi-turn conversations (8 to 16 parallel chains) targeting gemini-3.8-flash on the Interactions API (POST /v1beta/interactions).
In our recent test runs, all conversations completed cleanly without encountering the re-rooting issue.
Could you please re-run your repro script and let us know if you are still able to reproduce the issue..?
Thanks!
JasonSteving99 commentedon Sep 29, 2026
Hey @Venkaiahbabuneelam this is still happening. I'm not the only one running into this issue, colleagues have run into it as well. I attached a rerun that I ran just now.
rerun.log
Hold Gemini conversations in the workflow, and fail Gemini 4xx errors…
JasonSteving99 commentedon Oct 7, 2026
Anyone look into this? We had to workaround this by simply not using the interactions API with server managed context history and instead managing it manually on our side.
Venkaiahbabuneelam commentedon Oct 8, 2026
==============================================================================
Gemini Interactions API -- conversation re-root breaks previous_interaction_id
google-genai : 2.28.0
python : 3.13.7
model : gemini-3.8-flash
started (UTC): 2026-10-08T06:18:24Z
An interaction id is v1_: field 1 is the conversation ROOT id, field 2
is the interaction's OWN id. They should match only on a conversation's first turn.
Running 8 conversations concurrently; each prints its table when it
finishes. >> = re-rooted (root == self mid-chain) XX = function_result rejected
Conversation 2 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 8 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 4 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 1 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 5 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 3 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 7 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
Conversation 6 -- clean
turn status calls root (field 1) self (field 2) chained from (prev self) interaction id
Ended normally (the model replied in prose).
==============================================================================
re-rooted mid-chain : 0/8
rejected submissions: 0/8
No rejection this run -- it is sporadic. Re-run, or raise --conversations.
Venkaiahbabuneelam commentedon Oct 8, 2026
Hi @JasonSteving99, All 8 test conversations completed successfully without any errors, confirming that the Gemini API and function calls are working as expected.
Thanks
github-actions commentedon Oct 16, 2026
This issue has been marked as stale because it has been open for 7 days with no activity. It will be closed in 2 days if no further activity occurs.
github-actions commentedon Oct 18, 2026
This issue was closed because it has been inactive for 9 days. Please post a new issue if you need further assistance. Thanks!