Skip to content

Conversation

@cpsievert
Copy link
Collaborator

Summary

  • Fix serialization of ContentToolResult.error field when calling .get_turns() followed by .model_dump_json()
  • Add test covering tool call failure serialization

Problem

When a tool call fails and the error is stored in ContentToolResult.error, attempting to serialize the chat turns would fail because Python Exception objects are not JSON serializable by default.

Reprex

from chatlas import ChatOpenAI, UserTurn, AssistantTurn
from chatlas.types import ContentToolRequest, ContentToolResult

# Create a tool request and a failed result
request = ContentToolRequest(
    id="test-123",
    name="my_tool", 
    arguments={"x": 1},
)
result = ContentToolResult(
    value=None,
    error=Exception("Something went wrong"),  # <-- Exception not serializable
    request=request,
)

chat = ChatOpenAI(api_key="fake_key")
chat.set_turns([
    UserTurn("Call the tool"),
    AssistantTurn([request]),
    UserTurn([result]),
])

# This would fail with:
# pydantic_core._pydantic_core.PydanticSerializationError: 
#   Unable to serialize unknown type: <class 'Exception'>
turns = chat.get_turns()
turns_json = [x.model_dump_json() for x in turns]

Solution

Add a field_serializer and field_validator to ContentToolResult to handle the error field:

  • serialize_error: converts Exception to string for JSON output
  • validate_error: accepts string or Exception during deserialization, reconstructing a generic Exception from the string

This allows round-trip serialization/deserialization of turns containing failed tool results, though the specific exception type is not preserved (only the error message).

Test plan

  • Added test_json_serialize_with_tool_failure test that verifies serialization and deserialization of turns with tool errors
  • All existing tests pass (458 passed)
  • Type checking passes

🤖 Generated with Claude Code

cpsievert and others added 3 commits January 22, 2026 16:15
When a tool call fails and the error is stored in ContentToolResult.error,
calling .get_turns() and then .model_dump_json() would fail because
Exception objects are not JSON serializable by default.

This adds a field_serializer and field_validator to ContentToolResult
to handle serialization of the error field:
- serialize_error: converts Exception to string for JSON output
- validate_error: accepts string or Exception during deserialization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous cassette contained placeholder IDs (like "msg_missing_id")
that caused VCR body matching to fail in CI. Re-recorded with fresh
API responses containing proper IDs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cpsievert cpsievert force-pushed the fix-tool-result-error-serialization branch from 982a925 to a3d9728 Compare January 22, 2026 22:43
@cpsievert cpsievert requested a review from Copilot January 22, 2026 22:47

This comment was marked as resolved.

@cpsievert cpsievert merged commit c8157d8 into main Jan 22, 2026
9 checks passed
@cpsievert cpsievert deleted the fix-tool-result-error-serialization branch January 22, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant