Summary
When using Gemini 3.1 Pro (gemini-3.1-pro-preview) through DroidProxy, the Factory CLI (droid) rejects tool calls with:
Execute
↳ Error: command is required and must be a string
Claude (Opus 4.7) and other providers work fine from the same session — the issue is specific to Gemini's tool_use output.
Environment
- DroidProxy v1.8.8 (macOS app bundle at
~/Applications/DroidProxy.app)
CLIProxyAPIPlus v6.9.28-0-plus running on 127.0.0.1:8318
ThinkingProxy on localhost:8317
- Factory CLI (
droid) as client
- Model:
gemini-3.1-pro-preview with thinking_level=high
- macOS (darwin 25.4.0)
Reproduction
- Configure DroidProxy with Gemini 3.1 Pro at thinking level "high"
- Send a request from Factory CLI that should invoke the
Execute tool
- Observe the CLI error:
Execute → Error: command is required and must be a string
Observations from /tmp/droidproxy-debug.log
Proxy-side everything looks correct:
[2026-04-21T13:57:05Z] INCOMING REQUEST: POST /v1/messages
[2026-04-21T13:57:05Z] ORIGINAL BODY (first 500): {"model":"gemini-3.1-pro-preview","max_tokens":65536,...}
[2026-04-21T13:57:05Z] INJECTED Gemini thinking: level=high for model gemini-3.1-pro-preview
[2026-04-21T13:57:05Z] MODIFIED BODY (first 500): {"model":"gemini-3.1-pro-preview","generationConfig":{"thinkingConfig":{"thinking_level":"high"}},...}
[2026-04-21T13:57:05Z] THINKING INJECTED: true
- Request is well-formed
generationConfig.thinkingConfig.thinking_level=high injected by ThinkingProxy.swift
- No upstream HTTP errors logged (
~/.cli-proxy-api/logs/ has no error files newer than Apr 18)
- Both proxy ports (
:8317, :8318) are live and healthy
The error is emitted by the Factory CLI when it parses a tool_use block whose input is missing the command field (or contains an empty/non-string value). This suggests Gemini is returning a function-call chunk that cli-proxy-api-plus translates into a tool_use with incomplete args.
Likely cause
One of:
- Gemini's SSE stream emits a partial
functionCall chunk that the v1/messages translator forwards as a tool_use before the args are complete.
- Gemini hallucinates a call to
Execute without populating the required command arg.
- The Gemini-to-Anthropic translation in
cli-proxy-api-plus drops the arg when generationConfig.thinkingConfig.thinking_level=high changes the response shape (e.g., reasoning tokens interleaved with the tool call).
Next steps
Workaround
Switch to Claude (Opus 4.7) or another provider. Gemini is effectively unusable for tool-driven sessions until the malformed tool_use is fixed.
Summary
When using Gemini 3.1 Pro (
gemini-3.1-pro-preview) through DroidProxy, the Factory CLI (droid) rejects tool calls with:Claude (Opus 4.7) and other providers work fine from the same session — the issue is specific to Gemini's tool_use output.
Environment
~/Applications/DroidProxy.app)CLIProxyAPIPlusv6.9.28-0-plus running on127.0.0.1:8318ThinkingProxyonlocalhost:8317droid) as clientgemini-3.1-pro-previewwiththinking_level=highReproduction
ExecutetoolExecute → Error: command is required and must be a stringObservations from
/tmp/droidproxy-debug.logProxy-side everything looks correct:
generationConfig.thinkingConfig.thinking_level=highinjected byThinkingProxy.swift~/.cli-proxy-api/logs/has no error files newer than Apr 18):8317,:8318) are live and healthyThe error is emitted by the Factory CLI when it parses a
tool_useblock whoseinputis missing thecommandfield (or contains an empty/non-string value). This suggests Gemini is returning a function-call chunk thatcli-proxy-api-plustranslates into atool_usewith incomplete args.Likely cause
One of:
functionCallchunk that the v1/messages translator forwards as atool_usebefore the args are complete.Executewithout populating the requiredcommandarg.cli-proxy-api-plusdrops the arg whengenerationConfig.thinkingConfig.thinking_level=highchanges the response shape (e.g., reasoning tokens interleaved with the tool call).Next steps
ThinkingProxy(or tapcli-proxy-api-plusoutput) to capture the raw Gemini reply that produces the badtool_useblockthinking_level=medium/lowto check if the issue is triggered specifically by high reasoningcli-proxy-api-plusneeds an update that better handles interleaved reasoning + function-call chunks for Gemini 3.1tool_useblock only after the fullfunctionCallargs JSON has been receivedWorkaround
Switch to Claude (Opus 4.7) or another provider. Gemini is effectively unusable for tool-driven sessions until the malformed
tool_useis fixed.