microsoft/autogen · error · ValueError
The last message is not a BaseChatMessage.
Error message
The last message is not a BaseChatMessage.
What it means
TaskRunnerTool.return_value_as_string raises ValueError when created with return_value_as_last_message=True but the wrapped task's TaskResult has no messages or its last message is not a BaseChatMessage. The tool promises to return the final chat message as its string output, so a missing/invalid last message breaks that contract.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/tools/_task_runner_tool.py:59
async def run(self, args: TaskRunnerToolArgs, cancellation_token: CancellationToken) -> TaskResult:
"""Run the task and return the result."""
return await self._task_runner.run(task=args.task, cancellation_token=cancellation_token)
async def run_stream(
self, args: TaskRunnerToolArgs, cancellation_token: CancellationToken
) -> AsyncGenerator[BaseAgentEvent | BaseChatMessage | TaskResult, None]:
"""Run the task and yield events or messages as they are produced, the final :class:`TaskResult`
will be yielded at the end."""
async for event in self._task_runner.run_stream(task=args.task, cancellation_token=cancellation_token):
yield event
def return_value_as_string(self, value: TaskResult) -> str:
"""Convert the task result to a string."""
if self._return_value_as_last_message:
if value.messages and isinstance(value.messages[-1], BaseChatMessage):
return value.messages[-1].to_model_text()
raise ValueError("The last message is not a BaseChatMessage.")
parts: List[str] = []
for message in value.messages:
if isinstance(message, BaseChatMessage):
if message.source == "user":
continue
parts.append(f"{message.source}: {message.to_model_text()}")
return "\n\n".join(parts)
async def save_state_json(self) -> Mapping[str, Any]:
return await self._task_runner.save_state()
async def load_state_json(self, state: Mapping[str, Any]) -> None:
await self._task_runner.load_state(state)
View on GitHub (pinned to 027ecf0a37)
Solutions
- Use return_value_as_last_message=False (default) so the tool joins all chat messages into a string instead of requiring a valid last message.
- Ensure the inner team always terminates after at least one BaseChatMessage (e.g. a MaxMessageTermination after a TextMessage rather than before any output).
- Pre-check the TaskResult before conversion: if result.messages and isinstance(result.messages[-1], BaseChatMessage).
Example fix
# before tool = TaskRunnerTool(..., return_value_as_last_message=True) # team may end without a chat message # after tool = TaskRunnerTool(..., return_value_as_last_message=False) # falls back to joining all messages
Defensive patterns
Strategy: fallback
Validate before calling
result = await inner.run(task=task)
if not result.messages or not isinstance(result.messages[-1], BaseChatMessage):
raise ValueError("Inner task produced no final chat message; check team termination config") Type guard
from autogen_agentchat.messages import BaseChatMessage
def has_final_chat_message(result: TaskResult) -> bool:
return bool(result.messages) and isinstance(result.messages[-1], BaseChatMessage) Try / catch
try:
return tool.return_value_as_string(result)
except ValueError:
return "(task produced no final message)" # or fall back to joining available messages Prevention
- Prefer return_value_as_last_message=False unless the inner team reliably ends with a chat message.
- Configure termination so at least one TextMessage is emitted before the team stops.
When it happens
Trigger: Constructing TaskRunnerTool(description=..., args_type=..., return_value_as_last_message=True) around a team/agent whose run ends with zero messages or whose last item is an event (BaseAgentEvent) rather than a BaseChatMessage; running a task that terminates before any agent produces output.
Common situations: Wrapping a team that ends on an error/termination event without a final chat message; using the tool with return_value_as_last_message=True when the inner task yields only tool-call events.
Related errors
- Tool names must be unique: {tool_names}
- Model does not support function calling and tools were provi
- All agents must have a name.
- All agents must have a unique name.
- All agents in the workflow must be in the group chat.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/1a61f9a73637d0a9.
Report an issue: GitHub.