khoj-ai/khoj · error · ValidationError
An Entry cannot be associated with both a user and an agent.
Error message
An Entry cannot be associated with both a user and an agent.
What it means
Entry.save() raises ValidationError when an Entry row has both user and agent foreign keys set. Entries must be scoped to exactly one owner: either a KhojUser or an Agent, never both.
Source
Thrown at src/khoj/database/models/__init__.py:803
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE, default=None, null=True, blank=True)
agent = models.ForeignKey(Agent, on_delete=models.CASCADE, default=None, null=True, blank=True)
embeddings = VectorField(dimensions=None)
raw = models.TextField()
compiled = models.TextField()
heading = models.CharField(max_length=1000, default=None, null=True, blank=True)
file_source = models.CharField(max_length=30, choices=EntrySource.choices, default=EntrySource.COMPUTER)
file_type = models.CharField(max_length=30, choices=EntryType.choices, default=EntryType.PLAINTEXT)
file_path = models.CharField(max_length=400, default=None, null=True, blank=True)
file_name = models.CharField(max_length=400, default=None, null=True, blank=True)
url = models.URLField(max_length=400, default=None, null=True, blank=True)
hashed_value = models.CharField(max_length=100)
corpus_id = models.UUIDField(default=uuid.uuid4, editable=False)
search_model = models.ForeignKey(SearchModelConfig, on_delete=models.SET_NULL, default=None, null=True, blank=True)
file_object = models.ForeignKey(FileObject, on_delete=models.CASCADE, default=None, null=True, blank=True)
def save(self, *args, **kwargs):
if self.user and self.agent:
raise ValidationError("An Entry cannot be associated with both a user and an agent.")
class EntryDates(DbBaseModel):
date = models.DateField()
entry = models.ForeignKey(Entry, on_delete=models.CASCADE, related_name="embeddings_dates")
class Meta:
indexes = [
models.Index(fields=["date"]),
]
class UserRequests(DbBaseModel):
"""Stores user requests to the server for rate limiting."""
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)
slug = models.CharField(max_length=200)
View on GitHub (pinned to ae229ca894)
Solutions
- Decide the owner: set user=None when the entry belongs to an agent, or agent=None for user-owned entries.
- Audit code paths that copy/duplicate entries (cloning often copies both FKs).
- Add a form/serializer-level check so the constraint is caught before save.
Example fix
# before Entry.objects.create(user=user, agent=agent, compiled_content=content) # after Entry.objects.create(user=None, agent=agent, compiled_content=content)
Defensive patterns
Strategy: validation
Validate before calling
assert not (entry.user and entry.agent), "Entry cannot have both user and agent"
# before create:
Entry.objects.create(user=user if owner_is_user else None,
agent=agent if not owner_is_user else None,
compiled_content=content) Type guard
def entry_has_single_owner(entry) -> bool:
return bool(entry.user) != bool(entry.agent) Try / catch
from django.core.exceptions import ValidationError
try:
entry.save()
except ValidationError as e:
if "both a user and an agent" in str(e):
if keep_agent_owner:
entry.user = None
else:
entry.agent = None
entry.save()
else:
raise Prevention
- Decide ownership at creation time and set exactly one FK.
- Review clone/copy code paths that duplicate both FKs.
- Enforce single-owner in forms/serializers with a clean() hook.
When it happens
Trigger: Entry.objects.create(user=u, agent=a, ...) or setting entry.agent while entry.user is already set, then saving.
Common situations: Indexing code that attaches shared content to an agent while forgetting to clear the user field; bulk import scripts setting both ownership fields.
Related errors
- Invalid conversation_log format: {str(e)}
- 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/a479f411a21a2f83.
Report an issue: GitHub.