jamiepine/voicebox · error · ValueError

A profile with the name '{data.name}' already exists. Please

Error message

A profile with the name '{data.name}' already exists. Please choose a different name.

What it means

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.

Source

Thrown at backend/services/profiles.py:157

    data: VoiceProfileCreate,
    db: Session,
) -> VoiceProfileResponse:
    """
    Create a new voice profile.

    Args:
        data: Profile creation data
        db: Database session

    Returns:
        Created profile

    Raises:
        ValueError: If a profile with the same name already exists
    """
    existing_profile = db.query(DBVoiceProfile).filter_by(name=data.name).first()
    if existing_profile:
        raise ValueError(f"A profile with the name '{data.name}' already exists. Please choose a different name.")

    # Auto-set default_engine for preset profiles
    default_engine = data.default_engine
    voice_type = data.voice_type or "cloned"
    if voice_type == "preset" and data.preset_engine and not default_engine:
        default_engine = data.preset_engine

    validation_error = _validate_profile_fields(
        voice_type=voice_type,
        preset_engine=data.preset_engine,
        preset_voice_id=data.preset_voice_id,
        design_prompt=data.design_prompt,
        default_engine=default_engine,
    )
    if validation_error:
        raise ValueError(validation_error)

    db_profile = DBVoiceProfile(

View on GitHub (pinned to 51f49dea19)

Solutions

  1. List profiles first (GET /profiles) and reuse the existing one instead of recreating, or pick a distinct name.
  2. Make the client idempotent: on this error, treat it as 'already created' and fetch the profile by name.
  3. Add a DB-level unique constraint on VoiceProfile.name so races surface as IntegrityError instead of silent duplicates.

Example fix

// before
await create_profile({"name": "Morgan", "language": "en"}, db)
// after - resolve existing first
existing = get_profile_orm_by_name_or_id("Morgan", db)
if existing is None:
    await create_profile({"name": "Morgan", "language": "en"}, db)
Defensive patterns

Strategy: validation

Validate before calling

def name_is_available(name: str, db) -> bool:
    from ..database import VoiceProfile
    return db.query(VoiceProfile).filter_by(name=name).first() is None

# call before create_profile
if not name_is_available(data.name, db):
    raise HTTPException(409, f"Profile name '{data.name}' already in use")

Try / catch

try:
    await create_profile(data, db)
except ValueError as e:
    if "already exists" in str(e):
        # idempotent: fetch the existing profile by name
        return get_profile_orm_by_name_or_id(data.name, db)
    raise

Prevention

When it happens

Trigger: 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).

Common situations: 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'.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/c44f438a506b3cd0. Report an issue: GitHub.