{"record":{"id":"a312c056a0c55435","repo":"jamiepine/voicebox","slug":"a-preset-named-data-name-already-exists","errorCode":null,"errorMessage":"A preset named '{data.name}' already exists","messagePattern":"A preset named '(.+?)' already exists","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"backend/services/effects.py","lineNumber":66,"sourceCode":"    \"\"\"Get a preset by name.\"\"\"\n    p = db.query(DBEffectPreset).filter_by(name=name).first()\n    if not p:\n        return None\n    return _preset_response(p)\n\n\ndef create_preset(data: EffectPresetCreate, db: Session) -> EffectPresetResponse:\n    \"\"\"Create a new user effect preset.\"\"\"\n\n    chain_dicts = [e.model_dump() for e in data.effects_chain]\n    error = validate_effects_chain(chain_dicts)\n    if error:\n        raise ValueError(error)\n\n    # Check for duplicate name before insert\n    existing = db.query(DBEffectPreset).filter_by(name=data.name).first()\n    if existing:\n        raise ValueError(f\"A preset named '{data.name}' already exists\")\n\n    preset = DBEffectPreset(\n        id=str(uuid.uuid4()),\n        name=data.name,\n        description=data.description,\n        effects_chain=json.dumps(chain_dicts),\n        is_builtin=False,\n    )\n    db.add(preset)\n    try:\n        db.commit()\n    except IntegrityError:\n        db.rollback()\n        raise ValueError(f\"A preset named '{data.name}' already exists\")\n    db.refresh(preset)\n    return _preset_response(preset)\n\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/effects.py#L48-L84","documentation":"create_preset() queries DBEffectPreset by name before insert; if a row already has that name it raises ValueError. Names are globally unique across built-in and user presets (the DB also enforces uniqueness, see error 225). This is the optimistic pre-check that catches the common case.","triggerScenarios":"POST create-preset with a name colliding with an existing preset — either a built-in ('Robotic', 'Radio', 'Echo Chamber', 'Deep Voice' from BUILTIN_PRESETS) or another user preset.","commonSituations":"User reusing a built-in name; restoring a preset export over an existing name; double-submit in the UI.","solutions":["Choose a different name.","Call get_preset_by_name(name) first to detect the collision earlier and guide the user.","Delete or rename the existing preset before recreating."],"exampleFix":"# before\ncreate_preset(EffectPresetCreate(name='Radio', ...), db)\n\n# after — pick a unique name\nbase, n, name = 'Radio', 1, 'Radio'\nwhile get_preset_by_name(name, db):\n    n += 1\n    name = f'{base} ({n})'\ncreate_preset(EffectPresetCreate(name=name, ...), db)","handlingStrategy":"validation","validationCode":"from backend.services.effects import get_preset_by_name\n\ndef name_available(name, db) -> bool:\n    return get_preset_by_name(name, db) is None","typeGuard":null,"tryCatchPattern":"try:\n    create_preset(data, db)\nexcept ValueError as e:\n    if \"already exists\" in str(e):\n        # suggest an alternate name (e.g. append ' (1)')\n        ...\n    raise","preventionTips":["Reserve built-in preset names (Robotic, Radio, Echo Chamber, Deep Voice) on the client.","Pre-check with get_preset_by_name before enabling the submit button."],"tags":["effects","presets","duplicate","validation"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}