Skip to content

[Bug]: Anthropic SDK path missing large-integer precision guard (tool_use input) #47229

@abczsl520

Description

@abczsl520

Summary

The quoteUnsafeIntegerLiterals fix from #23170 only covers Ollama/llama.cpp JSON parsing paths. The Anthropic Messages API streaming path has the same precision loss bug for tool_use input arguments containing large integers (e.g., Discord snowflake IDs).

Root Cause

When streaming Anthropic responses, tool_use input is built by incrementally appending input_json_delta fragments into a buffer (jsonBuf), then parsed via the vendored partial-json-parser:

@anthropic-ai/sdk/_vendor/partial-json-parser/parser.mjs

The final line:

partialParse = (input) => JSON.parse(generate(unstrip(strip(tokenize(input)))));

The tokenize() step correctly identifies large numbers as type: "number" tokens, and generate() outputs them verbatim. But the final JSON.parse() converts them to IEEE 754 doubles, losing precision for integers > Number.MAX_SAFE_INTEGER.

Example:

  • Model outputs: {"to": 1481220477346119781}
  • tokenize(){type: "number", value: "1481220477346119781"}
  • generate(){"to": 1481220477346119781} (string, precision intact)
  • JSON.parse(){to: 1481220477346119700}precision lost

Impact

  • Discord messages fail with "Unknown Channel" (288 failures in 3 days on one channel alone)
  • Any tool_call argument with a large integer is silently corrupted
  • Models that output IDs as bare numbers (even Claude does this occasionally) are affected
  • The existing quoteUnsafeIntegerLiterals in OpenClaw's own JSON parsing paths does NOT help here because the Anthropic SDK parses tool input internally before OpenClaw sees it

Suggested Fix

Apply the same quoteUnsafeIntegerLiterals treatment to the Anthropic SDK's tool_use input parsing path. Options:

  1. Monkey-patch the vendored partial-json-parser to quote numbers > MAX_SAFE_INTEGER in generate() before JSON.parse()
  2. Post-process tool_use content blocks after MessageStream emits them — walk the parsed input object looking for rounded numbers and cross-reference with the raw jsonBuf string
  3. Intercept at the contentBlock event — before the parsed input is used, re-parse the raw JSON buffer using parseJsonPreservingUnsafeIntegers

Option 3 seems cleanest since jsonBuf (stored as JSON_BUF_PROPERTY) still contains the original string with full precision.

Version

  • OpenClaw: 2026.3.13 (61d171a)
  • @anthropic-ai/sdk: (bundled version)
  • Node: v25.6.1
  • Platform: macOS Darwin 25.2.0 (arm64)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions