HumanSignal/label-studio · error · NotFound

Project not found.

Error message

Project not found.

What it means

get_hotkey_project raises DRF NotFound after the ID format check when no Project matches both the given pk and the user's active organization. The lookup is scoped to the active organization, so a valid project ID from a different organization also yields 404 'Project not found.'

Source

Thrown at label_studio/users/hotkeys.py:22

from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError

PROJECT_ID_PATTERN = re.compile(r'^[1-9][0-9]*$')


def get_hotkey_project(user, project_id) -> Project | None:
    if project_id is None:
        return None

    if not isinstance(project_id, str) or PROJECT_ID_PATTERN.fullmatch(project_id) is None:
        raise ValidationError({'project': 'Project must be an integer.'}) from None

    project_id = int(project_id)
    project = Project.objects.filter(
        pk=project_id,
        organization=user.active_organization,
    ).first()
    if project is None:
        raise NotFound('Project not found.')
    if not project.has_permission(user):
        raise PermissionDenied('You do not have access to this project.')
    return project

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Verify the project ID exists and belongs to the user's currently active organization
  2. Switch the user's active organization to the one owning the project (PATCH /api/current-user with the org id or the org-switch endpoint)
  3. Refresh the frontend's project list and use a current project ID instead of a cached one
  4. Check the project wasn't deleted; list projects via GET /api/projects/ under the active org to find a valid ID

Example fix

// before
GET /api/hotkeys?project=999   # project lives in another org -> 404
// after
# switch to the org that owns the project, then
GET /api/hotkeys?project=999
Defensive patterns

Strategy: try-catch

Validate before calling

existing = [p.id for p in client.projects.list()]
if project_id not in existing:
    raise ValueError(f'project {project_id} not visible in active organization')

Type guard

def project_in_active_org(project, user):
    return project is not None and project.organization_id == user.active_organization_id

Try / catch

try:
    project = get_hotkey_project(user, project_id)
except NotFound:
    logger.warning('Project %s not found in active org; refreshing project list', project_id)
    projects = client.projects.list()
    project = next((p for p in projects if p.id == project_id), None)
    if project is None:
        raise

Prevention

When it happens

Trigger: GET/PATCH hotkey endpoints with ?project=<id> where the ID doesn't exist, was deleted, or belongs to another organization than the user's active_organization (multi-org users switching orgs while caching old IDs).

Common situations: Stale project IDs in frontend state after a project was deleted; users in multiple organizations whose active org changed (via UI switch or /api/current-user org switch) so previously valid IDs are invisible; copied URLs/bookmarks referencing projects from another org; typos in the project ID.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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