Skip to content

SDK returns empty text blocks, but does not accept them #461

Closed

Description

@eyurtsev

Using anthropic sdk via langchain_anthropic integration

from langchain_core.messages import AIMessage, HumanMessage, ToolMessage, SystemMessage
from langchain_anthropic import ChatAnthropic
from langchain_core.tools import tool

@tool
def type_letter(letter: str) -> str:
    """Type the given letter."""
    return "OK"


model = ChatAnthropic(model="claude-3-haiku-20240307", temperature=0).bind_tools([type_letter])

messages = [
    SystemMessage(content="Repeat the given string using the provided tools. Do not write anything else or provide any explanations. For example, if the string is 'abc', you must print the letters 'a', 'b', and 'c' one at a time and in that order. "),
    HumanMessage(content="dog")
]

model.invoke(messages)

The SDK can return empty text blocks from models:

ToolsBetaMessage(id='msg_01D6BbZbwbPYRVMPVu5SZRTp', content=[TextBlock(text='', type='text'), ToolUseBlock(id='toolu_01YHFB1pLY3xNa1edzoV4HtL', input={'letter': 'd'}, name='type_letter', type='tool_use'), ToolUseBlock(id='toolu_011ewRdDypyE8yHMniYT2gzj', input={'letter': 'o'}, name='type_letter', type='tool_use'), ToolUseBlock(id='toolu_01YKV1QaDPePiAFQVwmrSmjk', input={'letter': 'g'}, name='type_letter', type='tool_use')], model='claude-3-haiku-20240307', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=395, output_tokens=125))

However, the SDK does not accept empty text block if re-interacting with the model (e.g., if using an agent).

Activity

  1. eyurtsev commented on Apr 17, 2024

    @eyurtsev
    Author

    Here's an example of re-interaction with the model:

    from langchain_core.messages import AIMessage, HumanMessage, ToolMessage, SystemMessage
    from langchain_anthropic import ChatAnthropic
    from langchain_core.tools import tool
    
    @tool
    def type_letter(letter: str) -> str:
        """Type the given letter."""
        return "OK"
    
    
    model = ChatAnthropic(model="claude-3-opus-20240229", temperature=0).bind_tools([type_letter])
    
    
    messages = [
        SystemMessage(content="Repeat the given string using the provided tools. Do not write anything else or provide any explanations. For example, if the string is 'abc', you must print the letters 'a', 'b', and 'c' one at a time and in that order. "),
        HumanMessage(content="dog"),
        AIMessage(
            content=[
                {"text": "", "type": "text"},
                {
                    "id": "toolu_01V6d6W32QGGSmQm4BT98EKk",
                    "input": {
                        "letter": "d"
                    },
                    "name": "type_letter",
                    "type": "tool_use"
                },
            ],
            tool_calls=[
                {
                    "name": "type_letter",
                    "args": {
                        "letter": "d"
                    },
                    "id": "toolu_01V6d6W32QGGSmQm4BT98EKk"
                },
            ],
        ),
        ToolMessage(content="OK", tool_call_id="toolu_01V6d6W32QGGSmQm4BT98EKk"),
    ]
    
    model.invoke(messages)

    This results in a 4xx error:

    BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages: text content blocks must be non-empty'}}

    But this should be accepted since it's output by the sdk / model itself

  2. hinthornw commented on Apr 17, 2024

    @hinthornw

    Related code snippet:

    import anthropic
    
    client = anthropic.Client()
    
    client.beta.tools.messages.create(
        model="claude-3-haiku-20240307",
        max_tokens=1000,
        tools=[
            {
                "name": "tavily_search_results_json",
                "description": "A search engine optimized for comprehensive, accurate, and trusted results. Useful for when you need to answer questions about current events. Input should be a search query.",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "query": {
                            "description": "search query to look up",
                            "type": "string",
                        }
                    },
                    "required": ["query"],
                },
            }
        ],
        messages=[
            {
                "role": "user",
                "content": [{"type": "text", "text": "What's langgraph designed to do?"}],
            },
            {
                "role": "assistant",
                "content": [
                    {"text": "", "type": "text"},
                    {
                        "id": "toolu_01QxzCHR55x5RigzDdwLuQ5V",
                        "input": {"query": "foo"},
                        "name": "tavily_search_results_json",
                        "type": "tool_use",
                    },
                ],
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": "toolu_01QxzCHR55x5RigzDdwLuQ5V",
                        "content": "[Foo bar baz]",
                    },
                ],
            },
        ],
    )
    
  3. aaron-lerner commented on Apr 17, 2024

    @aaron-lerner
    Contributor

    Thanks for reporting. Working on fixing this asap!

  4. aaron-lerner commented on Apr 17, 2024

    @aaron-lerner
    Contributor

    This is now fixed.

  5. dedeswim commented on May 31, 2024

    @dedeswim

    Unless I am missing something, I still have the same issue with the following code:

    import anthropic
    
    client = anthropic.Client()
    
    messages = [
        {
            "content": [{"text": "How many appointments do I have today?", "type": "text"}],
            "role": "user",
        },
        {
            "content": [
                {
                    "text": '<thinking>\nTo find out how many appointments the user has today, I should use the get_day_calendar_events tool. This tool requires a "day" parameter in the format YYYY-MM-DD.\n\nEmma did not specify a date in her request, so I first need to determine what the current date is. I can use the get_current_day tool to retrieve that information.\n\nOnce I have the current date, I can pass that into the get_day_calendar_events tool to retrieve Emma\'s appointments for today.\n</thinking>',
                    "type": "text",
                },
                {
                    "id": "toolu_01UsBRMJWT8xAssuztCGEZNu",
                    "input": {},
                    "name": "get_current_day",
                    "type": "tool_use",
                },
            ],
            "role": "assistant",
        },
        {
            "content": [
                {
                    "tool_use_id": "toolu_01UsBRMJWT8xAssuztCGEZNu",
                    "type": "tool_result",
                    "content": [{"text": "2024-05-15", "type": "text"}],
                    "is_error": False,
                }
            ],
            "role": "user",
        },
        {
            "content": [
                {"text": "", "type": "text"},
                {
                    "id": "toolu_01YRKLXccBZjeQfYU2M7YLY8",
                    "input": {"day": "2024-05-15"},
                    "name": "get_day_calendar_events",
                    "type": "tool_use",
                },
            ],
            "role": "assistant",
        },
        {
            "content": [
                {
                    "tool_use_id": "toolu_01YRKLXccBZjeQfYU2M7YLY8",
                    "type": "tool_result",
                    "content": [{"text": "<TOOL OUTPUT HERE>", "type": "text"}],
                    "is_error": False,
                }
            ],
            "role": "user",
        },
    ]
    
    
    client.messages.create(
        model="claude-3-opus-20240229",
        max_tokens=1000,
        messages=messages,
    )

    This gives me the following error:

    anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages: text content blocks must be non-empty'}}
    
  6. aaron-lerner commented on May 31, 2024

    @aaron-lerner
    Contributor

    Hi @dedeswim, was this part of your request given as output by the API or did you put it together yourself?

        {
            "content": [
                {"text": "", "type": "text"},
                {
                    "id": "toolu_01YRKLXccBZjeQfYU2M7YLY8",
                    "input": {"day": "2024-05-15"},
                    "name": "get_day_calendar_events",
                    "type": "tool_use",
                },
            ],
            "role": "assistant",
        },
    

    The API returning 400 for {"text": "", "type": "text"} is correct, but the API returning this as content is not.

  7. dedeswim commented on May 31, 2024

    @dedeswim

    Hi @aaron-lerner, you are right, it's my fault! Sorry, I somewhat completely missed that line.

    Thanks a lot for the quick reply!

  8. mmichelli commented on Feb 12, 2025

    @mmichelli

    BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages: text content blocks must be non-empty'}}

    I'm getting this issue from AnthropicVertex.

  9. added a commit that references this issue on Mar 19, 2025
  10. added a commit that references this issue on Mar 21, 2025
  11. added a commit that references this issue on Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions