{"record":{"id":"09cd08c01bdd5ff3","repo":"BerriAI/litellm","slug":"bedrockexception-error-str","errorCode":null,"errorMessage":"BedrockException - {error_str}","messagePattern":"BedrockException - (.+?)","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"litellm/litellm_core_utils/exception_mapping_utils.py","lineNumber":845,"sourceCode":"        or \"Input is too long\" in error_str\n        or \"prompt is too long\" in error_str\n        or \"prompt: length: 1..\" in error_str\n        or \"Too many input tokens\" in error_str\n    ):\n        raise ContextWindowExceededError(\n            message=f\"BedrockException: Context Window Error - {error_str}\",\n            model=model,\n            llm_provider=\"bedrock\",\n        )\n    elif \"Conversation blocks and tool result blocks cannot be provided in the same turn.\" in error_str:\n        raise BadRequestError(\n            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.\",\n            model=model,\n            llm_provider=\"bedrock\",\n            response=getattr(original_exception, \"response\", None),\n        )\n    elif \"Malformed input request\" in error_str:\n        raise BadRequestError(\n            message=f\"BedrockException - {error_str}\",\n            model=model,\n            llm_provider=\"bedrock\",\n            response=getattr(original_exception, \"response\", None),\n        )\n    elif \"A conversation must start with a user message.\" in error_str:\n        raise BadRequestError(\n            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`\",\n            model=model,\n            llm_provider=\"bedrock\",\n            response=getattr(original_exception, \"response\", None),\n        )\n    elif (\n        \"Unable to locate credentials\" in error_str\n        or \"The security token included in the request is invalid\" in error_str\n    ):\n        raise AuthenticationError(\n            message=f\"BedrockException Invalid Authentication - {error_str}\",","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/exception_mapping_utils.py#L827-L863","documentation":"LiteLLM throws BadRequestError when Bedrock returns 'Malformed input request' - the request body does not match the target model's expected inference schema (bad message structure, unsupported field, invalid content block) and Bedrock refuses it before running inference. It is the generic 400 branch of the Bedrock mapper; the underlying error_str embedded in the message names the offending part. Same payload on a different Bedrock model can succeed because schemas differ per model family.","triggerScenarios":"litellm.completion(model='bedrock/...') with messages containing empty content, roles the model does not accept, model-unsupported parameters (logit_bias on Titan, top_k where unsupported), malformed image/system blocks, or a wrong inferenceProfileId embedded in the model string.","commonSituations":"Switching the bedrock/ model string without adapting the payload (Claude vs Titan vs Llama schemas differ); passing OpenAI-only fields through; empty-string content in a message after templating; Bedrock API drift after model version updates.","solutions":["Read the error_str inside the message - Bedrock usually names the exact offending field","Validate every message has non-empty content and a role the target model supports, and enable litellm drop_params=True to strip unsupported parameters","Reproduce the raw call with boto3 bedrock-runtime.invoke_model to isolate whether your payload or litellm's transformation is at fault","Verify the model id / inference profile string formatting (e.g. 'bedrock/us.anthropic.claude-3-5-sonnet-...:0')"],"exampleFix":"# before\nresp = litellm.completion(model=\"bedrock/amazon.titan-text-express-v1\", messages=messages, logit_bias={200: 2.0})\n\n# after\nimport litellm\nlitellm.drop_params = True  # strip params the model rejects\nmessages = [m for m in messages if m.get(\"content\")]  # drop empty-content blocks\nresp = litellm.completion(model=\"bedrock/amazon.titan-text-express-v1\", messages=messages)","handlingStrategy":"validation","validationCode":"import litellm\nlitellm.drop_params = True\n\nALLOWED_ROLES = {'system', 'user', 'assistant', 'tool'}\n\ndef payload_is_sane(messages: list) -> bool:\n    if not messages:\n        return False\n    return all(m.get('role') in ALLOWED_ROLES and m.get('content') for m in messages)","typeGuard":"import litellm\n\ndef is_malformed_request(e: BaseException) -> bool:\n    return isinstance(e, litellm.BadRequestError) and 'Malformed input' in str(e)","tryCatchPattern":"try:\n    resp = litellm.completion(model='bedrock/...', messages=messages)\nexcept litellm.BadRequestError as e:\n    log.error('bedrock rejected payload: %s', e)\n    raise  # fix payload per the embedded error text; do not retry as-is","preventionTips":["Lint messages (non-empty content, valid roles) before sending","Enable drop_params=True when switching between Bedrock model families","Reproduce new payload shapes with boto3 invoke_model before wiring into litellm","Pin model ids and payload shapes together - change both or neither"],"tags":["bedrock","bad-request","payload-validation","schema"],"backgroundTag":"invalid-request-payload","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}