Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
-->


## [Unreleased]

### Bug fixes

* `ChatBedrock()` (with the default `api="converse"`) no longer sends assistant turns with an empty `content` array, which Converse rejects. This happens when a response carries no content blocks, for example when a guardrail intervenes before the model produces any. A `"[empty string]"` placeholder is sent instead, matching how empty text content is already normalized. (#426)


## [0.23.0] - 2026-09-04

### New features
Expand Down
6 changes: 6 additions & 0 deletions chatlas/_provider_bedrock_converse.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,12 @@ def as_converse_messages(turns: list[Turn]) -> list[MessageUnionTypeDef]:
for c in turn.contents:
content.append(as_converse_content(c, document_index=index))
index += 1

# Converse requires non-empty content, and dropping the turn instead
# would leave two consecutive user messages.
if role == "assistant" and not content:
content = [{"text": "[empty string]"}]

messages.append({"role": role, "content": content})
return messages

Expand Down
22 changes: 22 additions & 0 deletions tests/test_provider_bedrock_converse.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,28 @@ def test_unknown_turn_role_raises(self):
with pytest.raises(ValueError, match="Unknown role"):
as_converse_messages([turn])

def test_empty_assistant_turn_gets_a_placeholder(self):
from chatlas._provider_bedrock_converse import as_converse_messages
from chatlas._turn import AssistantTurn, UserTurn

turns = [
UserTurn("Don't say anything"),
AssistantTurn([]),
UserTurn("What did I just say?"),
]
messages = as_converse_messages(turns)

assert [m["role"] for m in messages] == ["user", "assistant", "user"]
assert messages[1]["content"] == [{"text": "[empty string]"}]

def test_empty_user_turn_is_left_alone(self):
from chatlas._provider_bedrock_converse import as_converse_messages
from chatlas._turn import UserTurn

messages = as_converse_messages([UserTurn([])])

assert messages[0]["content"] == []


class TestRequestTransport:
def binary_request(self) -> "ConverseRequestTypeDef":
Expand Down
Loading