{"record":{"id":"c44f438a506b3cd0","repo":"jamiepine/voicebox","slug":"a-profile-with-the-name-data-name-already-exis","errorCode":null,"errorMessage":"A profile with the name '{data.name}' already exists. Please choose a different name.","messagePattern":"A profile with the name '(.+?)' already exists\\. Please choose a different name\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/services/profiles.py","lineNumber":157,"sourceCode":"    data: VoiceProfileCreate,\n    db: Session,\n) -> VoiceProfileResponse:\n    \"\"\"\n    Create a new voice profile.\n\n    Args:\n        data: Profile creation data\n        db: Database session\n\n    Returns:\n        Created profile\n\n    Raises:\n        ValueError: If a profile with the same name already exists\n    \"\"\"\n    existing_profile = db.query(DBVoiceProfile).filter_by(name=data.name).first()\n    if existing_profile:\n        raise ValueError(f\"A profile with the name '{data.name}' already exists. Please choose a different name.\")\n\n    # Auto-set default_engine for preset profiles\n    default_engine = data.default_engine\n    voice_type = data.voice_type or \"cloned\"\n    if voice_type == \"preset\" and data.preset_engine and not default_engine:\n        default_engine = data.preset_engine\n\n    validation_error = _validate_profile_fields(\n        voice_type=voice_type,\n        preset_engine=data.preset_engine,\n        preset_voice_id=data.preset_voice_id,\n        design_prompt=data.design_prompt,\n        default_engine=default_engine,\n    )\n    if validation_error:\n        raise ValueError(validation_error)\n\n    db_profile = DBVoiceProfile(","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/profiles.py#L139-L175","documentation":"Raised by create_profile() when a DBVoiceProfile row already exists with the same name. The check is application-level (db.query().filter_by(name=data.name).first()), performed before any field validation, so it fires even for otherwise-invalid payloads. The name column has no documented DB unique constraint, so concurrent inserts can race past this guard.","triggerScenarios":"POSTing a VoiceProfileCreate payload whose 'name' matches any existing profile row. The comparison is exact-match and case-sensitive (unlike the case-insensitive name lookup used elsewhere in get_profile_orm_by_name_or_id).","commonSituations":"Re-running a setup/seed script that creates the same profile twice; client retrying a create after a timeout where the first call actually succeeded; two users picking default names like 'Default' or 'Morgan'.","solutions":["List profiles first (GET /profiles) and reuse the existing one instead of recreating, or pick a distinct name.","Make the client idempotent: on this error, treat it as 'already created' and fetch the profile by name.","Add a DB-level unique constraint on VoiceProfile.name so races surface as IntegrityError instead of silent duplicates."],"exampleFix":"// before\nawait create_profile({\"name\": \"Morgan\", \"language\": \"en\"}, db)\n// after - resolve existing first\nexisting = get_profile_orm_by_name_or_id(\"Morgan\", db)\nif existing is None:\n    await create_profile({\"name\": \"Morgan\", \"language\": \"en\"}, db)","handlingStrategy":"validation","validationCode":"def name_is_available(name: str, db) -> bool:\n    from ..database import VoiceProfile\n    return db.query(VoiceProfile).filter_by(name=name).first() is None\n\n# call before create_profile\nif not name_is_available(data.name, db):\n    raise HTTPException(409, f\"Profile name '{data.name}' already in use\")","typeGuard":null,"tryCatchPattern":"try:\n    await create_profile(data, db)\nexcept ValueError as e:\n    if \"already exists\" in str(e):\n        # idempotent: fetch the existing profile by name\n        return get_profile_orm_by_name_or_id(data.name, db)\n    raise","preventionTips":["Generate names deterministically (e.g. namespaced) so retries don't create duplicates.","Add a UNIQUE index on VoiceProfile.name at the DB level to catch races.","Resolve-by-name before create to make the create path idempotent."],"tags":["profiles","duplicate","validation","create","name-conflict"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}