run-llama/llama_index · error · ValueError
Failed to serialize additional_kwargs value: {value}
Error message
Failed to serialize additional_kwargs value: {value} What it means
When a ChatMessage is serialized (e.g. SimpleChatStore.to_dict / json persistance), each value in ChatMessage.additional_kwargs is run through _recursive_serialization and must end up as a JSON primitive/container (str, int, float, bool, dict, list, None). Objects that survive recursion unchanged -- arbitrary class instances, datetime, enums without str conversion -- trigger this ValueError.
Source
Thrown at llama-index-core/llama_index/core/storage/chat_store/simple_chat_store.py:20
import os
from typing import Any, Dict, List, Optional
from typing_extensions import Annotated
import fsspec
from llama_index.core.bridge.pydantic import Field, WrapSerializer
from llama_index.core.llms import ChatMessage
from llama_index.core.storage.chat_store.base import BaseChatStore
def chat_message_serialization(
chat_message: Any, handler: Any, info: Any
) -> Dict[str, Any]:
partial_result = handler(chat_message, info)
for key, value in partial_result.get("additional_kwargs", {}).items():
value = chat_message._recursive_serialization(value)
if not isinstance(value, (str, int, float, bool, dict, list, type(None))):
raise ValueError(f"Failed to serialize additional_kwargs value: {value}")
partial_result["additional_kwargs"][key] = value
return partial_result
AnnotatedChatMessage = Annotated[
ChatMessage, WrapSerializer(chat_message_serialization)
]
class SimpleChatStore(BaseChatStore):
"""Simple chat store. Async methods provide same functionality as sync methods in this class."""
store: Dict[str, List[AnnotatedChatMessage]] = Field(default_factory=dict)
@classmethod
def class_name(cls) -> str:
"""Get class name."""View on GitHub (pinned to afd0fef371)
Solutions
- Keep additional_kwargs values JSON-native: store str/int/float/bool/dict/list only (e.g. model_dump() the object or str() an enum).
- Convert datetimes to ISO strings and dataclasses to dicts before attaching them to the message.
- If you control the object, add to-dict conversion in _recursive_serialization's supported types by using Pydantic-serializable models.
- Strip or transform non-serializable keys right before persistence (see validation code).
Example fix
# before
msg = ChatMessage(role='assistant', content='ok', additional_kwargs={'tool_call': tool_call_obj})
await store.set_messages('sess1', [msg])
store.persist('chat.json') # ValueError: Failed to serialize additional_kwargs value
# after
msg = ChatMessage(role='assistant', content='ok', additional_kwargs={'tool_call': tool_call_obj.model_dump()})
await store.set_messages('sess1', [msg])
store.persist('chat.json') Defensive patterns
Strategy: validation
Validate before calling
import json
def sanitize_additional_kwargs(msg) -> None:
for k, v in msg.additional_kwargs.items():
try:
json.dumps(v)
except (TypeError, ValueError):
msg.additional_kwargs[k] = str(v) # or model_dump()/isoformat() Type guard
def kwargs_are_json_safe(msg) -> bool:
try:
json.dumps(msg.additional_kwargs)
return True
except (TypeError, ValueError):
return False Try / catch
try:
store.persist(path)
except ValueError as e:
if 'Failed to serialize additional_kwargs' in str(e):
sanitize_additional_kwargs(msg) # then retry persist once
else:
raise Prevention
- Only attach JSON-native values (str/int/float/bool/dict/list/None) to ChatMessage.additional_kwargs.
- Convert datetimes to ISO strings and Pydantic/dataclass objects via model_dump()/asdict() at attach time.
- Run a json.dumps smoke test on messages before persisting a session.
When it happens
Trigger: Storing a chat message whose additional_kwargs contains a non-JSON value, e.g. additional_kwargs={'tool_call': ToolCall(...)} or {'ts': datetime.now()}, then calling chat_store.persist() / json.dumps via the store's serializer.
Common situations: Agent frameworks attaching rich objects (tool calls, metadata dataclasses, datetimes, enums) to ChatMessage.additional_kwargs; session persistence to disk/Redis of chat histories that were only ever used in memory before.
Related errors
- ChatStore loading requires a class_name
- Invalid ChatStore name: {chat_store_name}
- First argument to Readability constructor should be a docume
- Command failed: {command} {result.stderr}
- Must provide either user_msg or chat_history
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/b6626d819f44ab23.
Report an issue: GitHub.