Skip to content

[BUG] BedrockModel(strict_tools=True) rejects the entire ConverseStream when any tool has a oneOf schema or the tool set exceeds 24 aggregate optional params #2664

@tip-dteller

Description

@tip-dteller

Language Runtime Version

Python 3.13 (AWS Bedrock AgentCore runtime container, public.ecr.aws/docker/library/python:3.13-slim). Also reproduced locally on Python 3.14.4. strands-agents==1.42.0, botocore==1.43.6, boto3==1.43.6.

Operating System

Linux (Debian bookworm-slim container) on AWS Bedrock AgentCore. Also reproduced on macOS 26.5 (arm64).

Installation method

uv pip install from PyPI (pinned strands-agents>=1.42.0, resolved to 1.42.0).

Steps to reproduce

  1. Build a model with strict tools enabled:
    from strands.models.bedrock import BedrockModel
    model = BedrockModel(
        model_id="us.anthropic.claude-haiku-4-5-20251001-v1:0",
        strict_tools=True,
    )
  2. Create an Agent(model=model, tools=[...]) whose tool set either:
    • (a) includes a tool whose input JSON schema contains oneOf (for example, the strands-agents-tools AgentCore browser tool), or
    • (b) collectively declares more than 24 optional parameters across all tools (easy to hit with ~25+ tools, e.g. consolidated/dispatcher-style tools).
  3. Invoke the agent (sync agent(...) or streaming stream_async).

Expected Behavior

strict_tools should validate tool schemas against the provider's strict-mode constraints at agent/model build time and raise a clear, actionable error that names the offending tool — or skip/relax strict for incompatible tools with a warning — rather than letting the entire request fail opaquely at runtime. At minimum, the Bedrock strict-mode constraints (no oneOf; ≤ 24 aggregate optional params) should be documented for strict_tools.

Actual Behavior

The first converse_stream call raises botocore.errorfactory.ValidationException and the whole request is rejected — a single incompatible tool disables every invocation. Two distinct messages observed:

An error occurred (ValidationException) when calling the ConverseStream operation:
The model returned the following errors: tools.N.custom: Schema type 'oneOf' is not supported
An error occurred (ValidationException) when calling the ConverseStream operation:
The model returned the following errors: Schemas contains too many optional parameters (41),
which would make grammar compilation inefficient. Reduce the number of optional parameters
in your tool schemas (limit: 24).

Setting strict_tools=False (the default) resolves both, because non-strict Bedrock tolerates these schemas.

Truncated traceback:

File ".../strands/agent/agent.py", line 1024, in _execute_event_loop_cycle
File ".../strands/event_loop/event_loop.py", line 455, in _handle_model_execution
File ".../strands/event_loop/streaming.py", line 424, in process_stream
File ".../strands/models/bedrock.py", line 971, in _stream
    response = self.client.converse_stream(**request)
botocore.errorfactory.ValidationException: ... tools.26.custom: Schema type 'oneOf' is not supported

Additional Context

  • The 24-optional-param limit is aggregate across all tools in the request, not per-tool. No individual tool in our registry exceeded ~8 optional params, yet the combined total (41) tripped the limit — so the failure scales with the number of registered tools and is invisible when inspecting any single tool.
  • The failure mode is opaque: it surfaces as a runtime ValidationException deep inside converse_stream, not at tool/agent registration, so it is hard to attribute. In our case it caused a ~18-hour, 100%-of-invocations production outage that presented as "the agent returns nothing," with no Python traceback in the agent logic itself — only in the model call.
  • The bundled strands-agents/tools AgentCore browser tool ships a oneOf input schema, which makes it unusable under strict_tools=True. A cross-filed issue on strands-agents/tools may be warranted.
  • Suggestion: a build-time validate_tool_schemas_for_strict(model, tools) that fails fast naming tool.name, the violated constraint, and (for the aggregate limit) the running total — would turn an opaque production outage into an immediate, local error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-modelRelated to models or model providersarea-toolTool behavior/apibugSomething isn't workingpythonPull requests that update python code

    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