Describe the bug
A long-lived, mixed-model Copilot CLI session fails to continue with Gemini:
400 Tool name is required for Gemini requests
{"message":"Tool name is required for Gemini requests","code":"invalid_tool_call_format"}
Multiple normal prompts fail before any new tool executes. Manual /compact also fails with the same error, so compaction does not provide recovery in this session.
The captured failed compaction request provides a useful triage lead: its history contains three GPT-originated type: "custom" / custom.name: "apply_patch" calls among ordinary function calls. All tool results have matching, preceding calls with nonempty names when both call types are accounted for. This is not evidence of a missing tool name in the persisted call itself.
Suspected area: cross-model history normalization / Gemini request adaptation. This is a hypothesis, not a confirmed root cause or an assertion that two independent bugs exist.
Affected version
- Copilot CLI 1.0.86, verified from the running process's loaded
.../1.0.86/prebuilds/darwin-arm64/runtime.node.
- Session originally created under 1.0.83 and subsequently resumed across updates; the version that introduced the failure is unknown.
- Model at failure:
gemini-3.8-flash.
- Earlier turns used
gpt-6-astra, including built-in apply_patch.
- macOS 26.7, Apple Silicon (
arm64), tmux.
Steps to reproduce the behavior
Observed workflow, not yet a clean-room/minimal reproducer:
- Continue a long-lived session that has used both GPT and Gemini, with previous compactions and tool calls.
- GPT turns in that history use built-in
apply_patch, persisted as custom tool calls.
- Continue later with Gemini. Conversation-only rewinds and process resume/restart occurred before the reported failures. Their causal role has not been isolated; switching models alone is not claimed to reproduce this.
- Submit a normal follow-up prompt. It fails with
invalid_tool_call_format.
- Retry later: the same error recurs.
- Run
/compact: it also fails, with session.compaction_complete.success: false and error: "host-rethrow: 400 Tool name is required for Gemini requests".
The real environment includes user hooks, plugins, and MCP servers. These have not been eliminated in a fresh configuration. This report does not establish reproducibility in a stock installation.
Expected behavior
A session created through supported model switching, tool use, resume, and rewind should remain usable. Historical custom tool calls should be translated into a supported representation when replayed to another provider, or the CLI should provide an actionable compatibility/recovery error without silently discarding history.
Additional context
Captured request metadata
For the failed manual compaction, model.model_call_failure records:
{
"model": "gemini-3.8-flash",
"status": 400,
"api_endpoint": "/chat/completions",
"transport": "http",
"failure_kind": "api",
"badRequestKind": "structured_error",
"errorCode": "invalid_tool_call_format"
}
Parsing that event's JSON-encoded requestMessages locally:
| Check |
Result |
| Messages |
506 |
| Assistant tool calls |
258 |
Function calls with nonempty function.name |
255 |
Custom calls with nonempty custom.name |
3, all apply_patch |
| Tool-result messages |
258 |
| Results without a matching preceding named call |
0 |
The three custom calls are at zero-based message indices 85, 107, and 115; their matching results immediately follow. All 258 result messages omit a standalone name; each has a tool_call_id that resolves to its preceding call. This alone is not asserted to be invalid in the OpenAI-shaped intermediate format.
Synthetic structural illustration only (not an executed reproducer; IDs, input, and output replaced):
[
{
"role": "assistant",
"content": "",
"tool_calls": [{
"id": "custom_call_example",
"type": "custom",
"custom": {
"name": "apply_patch",
"input": "<synthetic patch placeholder>"
}
}]
},
{
"role": "tool",
"tool_call_id": "custom_call_example",
"content": "<synthetic result placeholder>"
}
]
Please check whether the Gemini adapter handles custom.name, rather than assuming every historical call has function.name. The captured request does not establish which field the server rejected; it is not a capture of the final native Gemini payload.
Trace correlation
| UTC time, 2026-09-19 |
Operation |
Request ID |
Service request ID |
| 21:44:48 |
Normal prompt: HTTP 400 |
7B0D:345026:2C3E730:36BEE94:6AAF024C |
138e7b2d-aebe-4123-97f2-8b61e81f383e |
| 22:07:00 |
Later normal prompt: HTTP 400 |
7F6E:178245:2FFDC9D:3C2C1FB:6AAF077F |
4b9439d5-7085-490b-8815-a43414f9cea4 |
| 22:07:20 |
Manual compaction: HTTP 400 |
4DFE:3B6359:2FDC2F9:3C0B645:6AAF0797 |
90eafc3c-9e21-4633-a126-9f3bfc45a047 |
Important limits / ruled-out inference
- Some persisted event
parentId links are dangling, but following those links alone incorrectly suggested an orphaned image-view result. The actual captured request contains both image-view calls, their names, and their results. Therefore, an orphan caused by rewind is not established.
- Successful later Gemini turns exist after the original custom-tool turns. This is not established as an immediate model-switch failure; resume/replay or runtime-version differences may matter.
- No controlled retry with only the custom calls normalized has been performed. No successful model-switch workaround is claimed.
- The live session was inspected read-only. No repair, event deletion, or history rewrite was performed for this investigation.
- No original conversation, image, patch contents, filesystem paths, or configuration is attached. Only structural findings and request-correlation metadata are included.
Related but not established as duplicates: broader Gemini 400 report and older tool-use/result corruption report.
Describe the bug
A long-lived, mixed-model Copilot CLI session fails to continue with Gemini:
Multiple normal prompts fail before any new tool executes. Manual
/compactalso fails with the same error, so compaction does not provide recovery in this session.The captured failed compaction request provides a useful triage lead: its history contains three GPT-originated
type: "custom"/custom.name: "apply_patch"calls among ordinary function calls. All tool results have matching, preceding calls with nonempty names when both call types are accounted for. This is not evidence of a missing tool name in the persisted call itself.Suspected area: cross-model history normalization / Gemini request adaptation. This is a hypothesis, not a confirmed root cause or an assertion that two independent bugs exist.
Affected version
.../1.0.86/prebuilds/darwin-arm64/runtime.node.gemini-3.8-flash.gpt-6-astra, including built-inapply_patch.arm64), tmux.Steps to reproduce the behavior
Observed workflow, not yet a clean-room/minimal reproducer:
apply_patch, persisted as custom tool calls.invalid_tool_call_format./compact: it also fails, withsession.compaction_complete.success: falseanderror: "host-rethrow: 400 Tool name is required for Gemini requests".The real environment includes user hooks, plugins, and MCP servers. These have not been eliminated in a fresh configuration. This report does not establish reproducibility in a stock installation.
Expected behavior
A session created through supported model switching, tool use, resume, and rewind should remain usable. Historical custom tool calls should be translated into a supported representation when replayed to another provider, or the CLI should provide an actionable compatibility/recovery error without silently discarding history.
Additional context
Captured request metadata
For the failed manual compaction,
model.model_call_failurerecords:{ "model": "gemini-3.8-flash", "status": 400, "api_endpoint": "/chat/completions", "transport": "http", "failure_kind": "api", "badRequestKind": "structured_error", "errorCode": "invalid_tool_call_format" }Parsing that event's JSON-encoded
requestMessageslocally:function.namecustom.nameapply_patchThe three custom calls are at zero-based message indices 85, 107, and 115; their matching results immediately follow. All 258 result messages omit a standalone
name; each has atool_call_idthat resolves to its preceding call. This alone is not asserted to be invalid in the OpenAI-shaped intermediate format.Synthetic structural illustration only (not an executed reproducer; IDs, input, and output replaced):
[ { "role": "assistant", "content": "", "tool_calls": [{ "id": "custom_call_example", "type": "custom", "custom": { "name": "apply_patch", "input": "<synthetic patch placeholder>" } }] }, { "role": "tool", "tool_call_id": "custom_call_example", "content": "<synthetic result placeholder>" } ]Please check whether the Gemini adapter handles
custom.name, rather than assuming every historical call hasfunction.name. The captured request does not establish which field the server rejected; it is not a capture of the final native Gemini payload.Trace correlation
7B0D:345026:2C3E730:36BEE94:6AAF024C138e7b2d-aebe-4123-97f2-8b61e81f383e7F6E:178245:2FFDC9D:3C2C1FB:6AAF077F4b9439d5-7085-490b-8815-a43414f9cea44DFE:3B6359:2FDC2F9:3C0B645:6AAF079790eafc3c-9e21-4633-a126-9f3bfc45a047Important limits / ruled-out inference
parentIdlinks are dangling, but following those links alone incorrectly suggested an orphaned image-view result. The actual captured request contains both image-view calls, their names, and their results. Therefore, an orphan caused by rewind is not established.Related but not established as duplicates: broader Gemini 400 report and older tool-use/result corruption report.