Skip to content

[Bug] Grok emits integer tool arguments as floats (120000.0) and routed calls are rejected before execution #1611

Description

@lidge-jun

Client or integration

Codex CLI

Provider or upstream service

xAI (xai/grok-4.5)

OpenCodex version

dev at 3982dae47 (observed live on the running service, 2.13.0)

Endpoint or capability

/v1/responses routed tool calls — integer tool arguments

Current behaviour

Grok serializes integer tool-call arguments as floats, and OpenCodex forwards the string through untouched. Codex then rejects the call before it ever runs, because its tool schemas declare those fields as integer types.

Every failure looks like this, and the tool never executes:

failed to parse function arguments: invalid type: floating point `120000.0`, expected u64
failed to parse function arguments: invalid type: floating point `29356.0`, expected i32
failed to parse function arguments: invalid type: floating point `12000.0`, expected usize

The .0 is present in the assembled arguments string that reaches the client, not something the client introduces. Extracted from a session rollout:

exec_command -> ["yield_time_ms":120000.0]
exec_command -> ["yield_time_ms":120000.0]
write_stdin  -> ["session_id":29356.0, "yield_time_ms":60000.0]
write_stdin  -> ["session_id":29356.0]

The model's intent is an integer in every case: yield_time_ms is a millisecond budget, and session_id is an exec session handle that was itself issued as 29356. Grok is round-tripping them through a float representation and emitting 29356.0.

This is not a JSON round-trip artifact inside OpenCodex. JSON.stringify(JSON.parse(...)) preserves integers exactly:

$ bun -e 'console.log(JSON.stringify(JSON.parse(String.raw`{"session_id":29356,"yield_time_ms":120000}`)))'
{"session_id":29356,"yield_time_ms":120000}

So the .0 arrives from upstream and survives because nothing on the routed path normalizes it. parseArgsObj in src/bridge.ts:246 only decides whether the arguments parse as an object; it does not reconcile argument values against the declared tool schema, and there is no integer coercion anywhere in src/adapters/ for tool-call arguments.

Expected behaviour

A float-valued argument whose declared schema type is integer should reach the client as an integer when the value is integral (Number.isInteger(120000.0) is true), so the tool call runs.

A non-integral value for an integer field is a genuine upstream error and should stay an error rather than being silently truncated.

Impact

Every affected turn is a hard failure, not a degradation: the tool call is rejected before execution, so the model loses the result and typically retries the same call with the same float. In the captured session this consumed five consecutive tool calls across exec_command and write_stdin without a single one running.

It is also transport-visible only on routed providers. The same Codex client works when the model emits real integers, which is why this reads as a Grok-specific tool-calling failure rather than a client bug.

Minimal redacted request or reproduction

  1. Route Codex CLI through OpenCodex at xai/grok-4.5.
  2. Ask for work that makes the model call a tool with an integer argument — any exec_command where it chooses a yield_time_ms, or any write_stdin reusing a session_id.
  3. Observe the function_call_output for that call.

Observed: failed to parse function arguments: invalid type: floating point 120000.0, expected u64, and the command does not run.

Expected: the call executes.

Scope check

Occurrences in local session rollouts are xai/grok-4.5 only. Five distinct values across two tool names (exec_command, write_stdin) and four Rust integer types (u64, i64, i32, usize), which is consistent with a serializer-level behavior on the provider side rather than one bad tool schema.

I have not verified whether other xAI models or other providers do the same; the sample here is one provider.

Logs or error output

{"type":"function_call_output","output":"failed to parse function arguments: invalid type: floating point `120000.0`, expected u64 at line 1 column 310"}
{"type":"function_call_output","output":"failed to parse function arguments: invalid type: floating point `120000.0`, expected u64 at line 1 column 305"}
{"type":"function_call_output","output":"failed to parse function arguments: invalid type: floating point `29356.0`, expected i32"}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions