HumanSignal/label-studio · error · ProjectExistException

Project with the same name already exists: {title}

Error message

Project with the same name already exists: {title}

What it means

Projects enforce a unique (title, created_by_id) constraint. When creating a project whose title duplicates one of the same user's projects, the IntegrityError is translated to ProjectExistException with this message. It is an application-level duplicate-name error, not a DB failure.

Source

Thrown at label_studio/projects/api.py:220

    def get_serializer(self, *args, **kwargs):
        sparse_fields = self.get_sparse_fields()
        if self.request.method == 'GET' and sparse_fields is not None:
            fields_param = settings.REST_FLEX_FIELDS.get('FIELDS_PARAM', 'fields')
            kwargs[fields_param] = sparse_fields
        return super().get_serializer(*args, **kwargs)

    def get_serializer_context(self):
        context = super(ProjectListAPI, self).get_serializer_context()
        context['created_by'] = self.request.user
        return context

    def perform_create(self, ser):
        try:
            ser.save(organization=self.request.user.active_organization)
        except IntegrityError as e:
            if str(e) == 'UNIQUE constraint failed: project.title, project.created_by_id':
                raise ProjectExistException(
                    'Project with the same name already exists: {}'.format(ser.validated_data.get('title', ''))
                )
            raise LabelStudioDatabaseException('Database error during project creation. Try again.')

    def get(self, request, *args, **kwargs):
        return super(ProjectListAPI, self).get(request, *args, **kwargs)

    @api_webhook(WebhookAction.PROJECT_CREATED)
    def post(self, request, *args, **kwargs):
        return super(ProjectListAPI, self).post(request, *args, **kwargs)


@method_decorator(
    name='get',
    decorator=extend_schema(
        tags=['Projects'],
        summary="List projects' counts",
        parameters=[

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Rename the new project to a unique title
  2. List existing projects (GET /api/projects) and reuse or delete the duplicate
  3. Check str(err) for the exact UNIQUE constraint string before assuming it's the name clash
  4. Wrap creation in a check: Project.objects.filter(title=title, created_by=user).exists()

Example fix

// before
axios.post('/api/projects', { title: 'My Project' }) // 400 ProjectExistException
// after
const { data: existing } = await axios.get('/api/projects?title=My Project');
if (existing.results.length === 0) {
  await axios.post('/api/projects', { title: 'My Project' });
} else {
  title = 'My Project 2'; // or reuse existing project
}
Defensive patterns

Strategy: validation

Validate before calling

if Project.objects.filter(title=title, created_by=user).exists():
    raise ValueError(f'Project with the same name already exists: {title}')

Try / catch

try:
    project = await axios.post('/api/projects', { title });
catch (e) {
  if (e.response?.data?.includes?.('already exists')) {
    // reuse or rename
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/projects with a title identical to an existing project owned by the same user (exact string match; DB UNIQUE constraint on project.title + project.created_by_id).

Common situations: Re-running an import/setup script twice; copying an existing project's title in the UI; automated test fixtures creating the same-named project; case differences are NOT distinguished beyond DB collation.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/f87ce2e617e07339. Report an issue: GitHub.