khoj-ai/khoj · error · ValidationError
Invalid conversation_log format: {str(e)}
Error message
Invalid conversation_log format: {str(e)} What it means
Entry.save() calls clean(), which validates that conversation_log['chat'] is a list of pydantic ChatMessageModel objects. Any exception during .get('chat') or model_validate is re-raised as a Django ValidationError.
Source
Thrown at src/khoj/database/models/__init__.py:679
client = models.ForeignKey(ClientApplication, on_delete=models.CASCADE, default=None, null=True, blank=True)
# Slug is an app-generated conversation identifier. Need not be unique. Used as display title essentially.
slug = models.CharField(max_length=200, default=None, null=True, blank=True)
# The title field is explicitly set by the user.
title = models.CharField(max_length=500, default=None, null=True, blank=True)
agent = models.ForeignKey(Agent, on_delete=models.SET_NULL, default=None, null=True, blank=True)
file_filters = models.JSONField(default=list)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, primary_key=True, db_index=True)
def clean(self):
# Validate conversation_log structure
try:
messages = self.conversation_log.get("chat", [])
for msg in messages:
ChatMessageModel.model_validate(msg)
except Exception as e:
raise ValidationError(f"Invalid conversation_log format: {str(e)}")
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
@property
def messages(self) -> List[ChatMessageModel]:
"""Type-hinted accessor for conversation messages"""
validated_messages = []
for msg in self.conversation_log.get("chat", []):
try:
# Clean up inferred queries if they contain None
if msg.get("intent") and msg["intent"].get("inferred_queries"):
msg["intent"]["inferred-queries"] = [
q for q in msg["intent"]["inferred_queries"] if q is not None and isinstance(q, str)
]
msg["message"] = str(msg.get("message", ""))
validated_messages.append(ChatMessageModel.model_validate(msg))View on GitHub (pinned to ae229ca894)
Solutions
- Inspect str(e) in the message to see which field failed pydantic validation.
- Build conversation_log entries with ChatMessageModel.model_validate(msg) (or construct model instances and use .model_dump()) before assigning.
- If migrating old data, write a normalization step mapping legacy keys to the current schema.
Example fix
# before
chat.conversation_log = {"chat": [{"role": "user", "text": "hi"}]} # wrong keys
chat.save() # ValidationError
# after
from khoj.database.models import ChatMessage
msg = ChatMessage(role="user", content="hi") # pydantic model
chat.conversation_log = {"chat": [msg.model_dump()]}
chat.save() Defensive patterns
Strategy: validation
Validate before calling
from pydantic import ValidationError as PydanticError
from khoj.database.models import ChatMessage
def valid_conversation_log(log: dict) -> bool:
try:
for msg in log.get("chat", []):
ChatMessage.model_validate(msg)
return True
except PydanticError:
return False
if not valid_conversation_log(chat.conversation_log):
raise HTTPException(400, "bad conversation_log")
chat.save() Type guard
def is_valid_conversation_log(log) -> bool:
return isinstance(log, dict) and isinstance(log.get("chat"), list) Try / catch
from django.core.exceptions import ValidationError
try:
chat.save()
except ValidationError as e:
if "Invalid conversation_log format" in str(e):
# log details, quarantine row, or normalize messages
...
raise Prevention
- Always construct chat messages via the pydantic ChatMessage model and .model_dump().
- Never hand-write conversation_log dicts; reuse message objects from the chat pipeline.
- Add a normalization step when migrating data between khoj versions.
When it happens
Trigger: Saving a Chat model object whose conversation_log lacks a 'chat' key, has non-list 'chat', or contains message dicts missing/typoing required ChatMessageModel fields (e.g. 'message' key absent).
Common situations: Hand-built or migrated conversation_log dicts; schema drift after upgrading khoj's ChatMessageModel; third-party code writing raw dicts with wrong keys.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- An Entry cannot be associated with both a user and an agent.
- Invalid automation id: {automation_id}
- A public Agent with the name {instance.name} already exists.
- A private Agent with the name {instance.name} already exists
- Invalid conversation settings. Configure some chat model on
AI-assisted analysis of khoj-ai/khoj@ae229ca894 (2026-08-27).
Data as JSON: /api/errors/4557a86d144efa0a.
Report an issue: GitHub.