BerriAI/litellm · error · BadRequestError
BedrockException - . Enable 'litellm.modify_params=True'…
Error message
BedrockException - {error_str}
. Enable 'litellm.modify_params=True' (for PROXY do: `litellm_settings::modify_params: True`) to insert a dummy assistant message and fix this error. What it means
LiteLLM throws BadRequestError when Bedrock's Converse API rejects the message list because conversation blocks and tool result blocks appear in the same turn (a user turn carries tool results while assistant content is also present). LiteLLM can auto-repair this shape by inserting a dummy assistant message, but only when litellm.modify_params is enabled; the exception message spells out that exact setting. It is a client-side (400) error: same payload plus modify_params=True succeeds.
Solutions
- Enable the fix: litellm.modify_params = True in code (env LITELLM_MODIFY_PARAMS=True), or on the proxy litellm_settings: modify_params: True, so LiteLLM inserts the dummy assistant message
- Restructure messages yourself: put tool results in their own turn per Bedrock Converse rules (assistant tool_use turn, then tool-result turn, then next user text)
- Upgrade litellm - Bedrock tool-turn transformation receives ongoing fixes
- If you must keep modify_params off, insert a minimal assistant message ({'role':'assistant','content':'.'}) before the tool results
Example fix
# before litellm.completion(model="bedrock/anthropic.claude-3-sonnet-...") # raises: Conversation blocks and tool result blocks in same turn # after import litellm litellm.modify_params = True litellm.completion(model="bedrock/anthropic.claude-3-sonnet-...", messages=messages, tools=tools)
Defensive patterns
Strategy: validation
Validate before calling
import litellm
litellm.modify_params = True # let LiteLLM insert the dummy assistant message
def bedrock_safe_messages(messages: list) -> list:
out = []
for m in messages:
if m.get('role') == 'tool' and (not out or out[-1].get('role') != 'assistant'):
out.append({'role': 'assistant', 'content': '.'}) # dummy assistant turn
out.append(m)
return out Type guard
import litellm
def is_bedrock_bad_request(e: BaseException) -> bool:
return isinstance(e, litellm.BadRequestError) and 'tool result blocks' in str(e) Try / catch
try:
resp = litellm.completion(model='bedrock/...', messages=messages, tools=tools)
except litellm.BadRequestError as e:
if 'tool result blocks' in str(e):
litellm.modify_params = True
resp = litellm.completion(model='bedrock/...', messages=messages, tools=tools)
else:
raise Prevention
- Keep litellm.modify_params=True when doing tool calling on Bedrock Converse models
- Always order tool turns as assistant tool_use -> tool result -> next user message
- Test agent tool loops against Bedrock specifically, not just OpenAI
- After trimming history, re-validate that each tool result is preceded by an assistant turn
When it happens
Trigger: Calling litellm.completion(model='bedrock/...', tools=[...]) for the turn after a tool call, where the follow-up messages array places tool results and conversation blocks in one turn - typical when hand-building tool-response messages with OpenAI-style role='tool' ordering instead of the Converse-required assistant tool_use -> tool result -> user sequence.
Common situations: Agent loops that append tool output as a user message right after the assistant tool_use turn; porting OpenAI tool-calling code to Bedrock without reordering messages; default-safe litellm.modify_params=False so the dummy assistant message is never inserted.
Related errors
- BedrockException - \n. Pass in default user message via…
- AgentCore: Failed to read/parse JSON response body
- Amazon Nova Canvas INPAINTING requires either maskPrompt or…
- Amazon Nova Canvas requires a text prompt. Pass a non-empty…
- Batch record for /v1/completions is missing required…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/f35684f225f67b94.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/litellm_core_utils/exception_mapping_utils.py:838
exception_type: str,
exception_provider: str,
extra_information: str,
) -> None:
if (
"too many tokens" in error_str
or "expected maxLength:" in error_str
or "Input is too long" in error_str
or "prompt is too long" in error_str
or "prompt: length: 1.." in error_str
or "Too many input tokens" in error_str
):
raise ContextWindowExceededError(
message=f"BedrockException: Context Window Error - {error_str}",
model=model,
llm_provider="bedrock",
)
elif "Conversation blocks and tool result blocks cannot be provided in the same turn." in error_str:
raise BadRequestError(
message=f"BedrockException - {error_str}\n. Enable 'litellm.modify_params=True' (for PROXY do: `litellm_settings::modify_params: True`) to insert a dummy assistant message and fix this error.",
model=model,
llm_provider="bedrock",
response=getattr(original_exception, "response", None),
)
elif "Malformed input request" in error_str:
raise BadRequestError(
message=f"BedrockException - {error_str}",
model=model,
llm_provider="bedrock",
response=getattr(original_exception, "response", None),
)
elif "A conversation must start with a user message." in error_str:
raise BadRequestError(
message=f"BedrockException - {error_str}\n. Pass in default user message via `completion(..,user_continue_message=)` or enable `litellm.modify_params=True`.\nFor Proxy: do via `litellm_settings::modify_params: True` or user_continue_message under `litellm_params`",
model=model,
llm_provider="bedrock",
response=getattr(original_exception, "response", None),View on GitHub (pinned to 77b7c6c40c)