Skip to content

400 Bad Request with Anthropic models when using custom tools with nested object schemas #48

@Tarquinen

Description

@Tarquinen

Summary

Anthropic models via the antigravity provider fail with a 400 Bad Request when custom tools contain nested object schemas with enums, optional fields, and record types.

Environment

  • Branch: dev
  • Provider: antigravity
  • Model: antigravity/claude-opus-4-5

Tool Schema That Causes the Issue

description: TOOL_DESCRIPTION,
args: {
    ids: tool.schema.array(
        tool.schema.string()
    ).describe(
        "Numeric IDs as strings to prune from the <prunable-tools> list"
    ),
    metadata: tool.schema.object({
        reason: tool.schema.enum(["completion", "noise", "consolidation"]).describe("The reason for pruning"),
        distillation: tool.schema.record(tool.schema.string(), tool.schema.any()).optional().describe(
            "An object containing detailed summaries or extractions of the key findings from the tools being pruned. This is REQUIRED for 'consolidation'."
        ),
    }).describe("Metadata about the pruning operation."),
},

Error Output

Acquiring credential for model antigravity/claude-opus-4-5. Tried credentials: 0/1(5)
Acquired key antigravity_oauth_1.json for model antigravity/claude-opus-4-5 (tier: standard-tier, priority: 2, selection: sequential, quota: 2/250 [99%])
Attempting stream with credential antigravity_oauth_1.json (Attempt 1/2)
Stream connection established for credential antigravity_oauth_1.json. Processing response.
Caught a critical API error mid-stream: HTTPStatusError. Signaling for credential rotation.
Released credential antigravity_oauth_1.json from model antigravity/claude-opus-4-5 (remaining concurrent: 0)
STREAM FINISHED and lock released for credential antigravity_oauth_1.json.
API call failed for model antigravity/claude-opus-4-5 with key antigravity_oauth_1.json. Error: StreamedAPIError. See failures.log for details.
Non-recoverable error (invalid_request) during custom stream. Failing.
An unhandled exception occurred in streaming retry logic: Provider error received in stream

Full Traceback

Traceback (most recent call last):
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/client.py", line 690, in _safe_streaming_wrapper
    chunk = await stream_iterator.__anext__()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/providers/antigravity_provider.py", line 4671, in _streaming_with_retry
    async for chunk in self._handle_streaming(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<9 lines>...
        yield chunk  # Stream immediately - true streaming preserved
        ^^^^^^^^^^^
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/providers/antigravity_provider.py", line 4545, in _handle_streaming
    response.raise_for_status()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/dan/src/LLM-API-Key-Proxy/venv/lib/python3.13/site-packages/httpx/_models.py", line 829, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:streamGenerateContent?alt=sse'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/client.py", line 1925, in _streaming_acompletion_with_retry
    raise last_exception
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/client.py", line 1888, in _streaming_acompletion_with_retry
    async for chunk in stream_generator:
        yield chunk
  File "/home/dan/src/LLM-API-Key-Proxy/src/rotator_library/client.py", line 783, in _safe_streaming_wrapper
    raise StreamedAPIError("Provider error received in stream", data=e)
rotator_library.client.StreamedAPIError: Provider error received in stream

Additional Notes

  • Nothing is logged to failures.log despite the error message suggesting it should be
  • The issue appears to be related to how nested object schemas with enum, optional, and record types are being converted/passed to the Gemini API endpoint
  • The 400 error comes from Google's internal endpoint (daily-cloudcode-pa.sandbox.googleapis.com), suggesting the tool schema conversion to Gemini format may be malformed

@MirRobot please analyze this issue and open a PR with a fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions