fix(anthropic): point the text attachment decode 400 at a file block's format
Some checks are pending
Cost map pins recheck / rerun-cost-map-guard (push) Waiting to run
LiteLLM Rust DB / db-queries (push) Waiting to run
LiteLLM Rust / rust-lint (push) Waiting to run
LiteLLM Rust / rust-test (push) Waiting to run
LiteLLM Rust / rust-wheel (push) Waiting to run

A downloaded text file reaches the decoder without its server's charset since main strips it, so the old hint to name the charset in the data URI could not help a URL caller. A file block's format takes text/plain;charset=... for both URLs and data URIs
This commit is contained in:
mateo-berri 2026-10-30 15:24:04 -07:00
parent c0b24323e8
commit d0bb701c34
2 changed files with 21 additions and 1 deletions

View file

@ -1856,7 +1856,8 @@ def _anthropic_text_document_source(
except (LookupError, UnicodeDecodeError) as decode_error:
raise litellm.BadRequestError(
message=f"Text attachment could not be read as {charset!r}: {decode_error}. "
"Send it as utf-8, or name its encoding in the data URI (data:text/plain;charset=...).",
"Send it as utf-8, or name its encoding (text/plain;charset=...) in the data URI "
"or in a file block's format.",
model=None,
llm_provider="anthropic",
) from decode_error

View file

@ -9389,6 +9389,25 @@ def test_anthropic_messages_pt_rejects_a_text_attachment_it_cannot_decode():
assert "utf-8" in str(raised.value)
assert undeclared_latin1.split(",", 1)[1] not in str(raised.value)
assert "file block's format" in str(raised.value)
def test_anthropic_messages_pt_reads_a_text_file_block_in_the_charset_its_format_names():
undeclared_latin1: Final = "data:text/plain;base64," + base64.b64encode("caf\xe9".encode("iso-8859-1")).decode()
messages: Final = [
{
"role": "user",
"content": [
{"type": "file", "file": {"file_data": undeclared_latin1, "format": "text/plain;charset=iso-8859-1"}}
],
}
]
result: Final = anthropic_messages_pt(messages=messages, model="claude-sonnet-5", llm_provider="anthropic")
assert result[0]["content"] == [
{"type": "document", "source": {"type": "text", "media_type": "text/plain", "data": "café"}}
]
@pytest.mark.parametrize("native_input", [{"city": "lyon"}, "[1, 2]"])