khoj-ai/khoj · error · ValidationError

A public Agent with the name {instance.name} already exists.

Error message

A public Agent with the name {instance.name} already exists.

What it means

Django pre_save signal on the Agent model rejecting creation of a new Agent whose name collides with an existing PUBLIC agent. Enforces globally unique public agent names.

Source

Thrown at src/khoj/database/models/__init__.py:370

    class Operation(models.TextChoices):
        INDEX_CONTENT = "index_content"
        SCHEDULED_JOB = "scheduled_job"
        SCHEDULE_LEADER = "schedule_leader"
        APPLY_MIGRATIONS = "apply_migrations"

    # We need to make sure that some operations are thread-safe. To do so, add locks for potentially shared operations.
    # For example, we need to make sure that only one process is updating the embeddings at a time.
    name = models.CharField(max_length=200, choices=Operation.choices, unique=True)
    started_at = models.DateTimeField(auto_now_add=True)
    max_duration_in_seconds = models.IntegerField(default=60 * 60 * 12)  # 12 hours


@receiver(pre_save, sender=Agent)
def verify_agent(sender, instance, **kwargs):
    # check if this is a new instance
    if instance._state.adding:
        if Agent.objects.filter(name=instance.name, privacy_level=Agent.PrivacyLevel.PUBLIC).exists():
            raise ValidationError(f"A public Agent with the name {instance.name} already exists.")
        if Agent.objects.filter(name=instance.name, creator=instance.creator).exists():
            raise ValidationError(f"A private Agent with the name {instance.name} already exists.")


class NotionConfig(DbBaseModel):
    token = models.CharField(max_length=200)
    user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)


class GithubConfig(DbBaseModel):
    pat_token = models.CharField(max_length=200)
    user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)


class GithubRepoConfig(DbBaseModel):
    name = models.CharField(max_length=200)
    owner = models.CharField(max_length=200)
    branch = models.CharField(max_length=200)

View on GitHub (pinned to ae229ca894)

Solutions

  1. Choose a different, unique name for the new agent.
  2. If the intent was to update the existing public agent, fetch and modify it instead of creating a new instance.
  3. Make seeding idempotent with get_or_create / existence checks before create.

Example fix

# before
Agent.objects.create(name="Research", privacy_level=Agent.PrivacyLevel.PUBLIC, creator=user)

# after
if Agent.objects.filter(name="Research", privacy_level=Agent.PrivacyLevel.PUBLIC).exists():
    agent = Agent.objects.get(name="Research", privacy_level=Agent.PrivacyLevel.PUBLIC)
else:
    agent = Agent.objects.create(name="Research", privacy_level=Agent.PrivacyLevel.PUBLIC, creator=user)
Defensive patterns

Strategy: validation

Validate before calling

from khoj.database.models import Agent
name = "Research"
if Agent.objects.filter(name=name, privacy_level=Agent.PrivacyLevel.PUBLIC).exists():
    agent = Agent.objects.get(name=name, privacy_level=Agent.PrivacyLevel.PUBLIC)
else:
    agent = Agent.objects.create(name=name, privacy_level=Agent.PrivacyLevel.PUBLIC, creator=user)

Try / catch

from django.core.exceptions import ValidationError
try:
    agent.save()
except ValidationError as e:
    if "public Agent" in str(e):
        # pick a new name or fetch existing
        agent = Agent.objects.get(name=agent.name, privacy_level=Agent.PrivacyLevel.PUBLIC)
    else:
        raise

Prevention

When it happens

Trigger: Agent.objects.create(name='x', privacy_level=PUBLIC) or saving a new Agent (via admin, DRF serializer, or ORM) when a public Agent named 'x' already exists.

Common situations: Seeding scripts run twice; users trying to shadow popular public agents; concurrent creation of same-named public agents.

Related errors


AI-assisted analysis of khoj-ai/khoj@ae229ca894 (2026-08-27). Data as JSON: /api/errors/923e828d5cec0994. Report an issue: GitHub.