{"record":{"id":"6c2f9bf3faac0a85","repo":"jamiepine/voicebox","slug":"exception-message-from-create-preset-valueerror","errorCode":null,"errorMessage":"{exception message from create_preset (ValueError)}","messagePattern":"\\{exception message from create_preset \\(ValueError\\)\\}","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"backend/routes/effects.py","lineNumber":104,"sourceCode":"\n    preset = effects_mod.get_preset(preset_id, db)\n    if not preset:\n        raise HTTPException(status_code=404, detail=\"Preset not found\")\n    return preset\n\n\n@router.post(\"/effects/presets\", response_model=models.EffectPresetResponse)\nasync def create_effect_preset(\n    data: models.EffectPresetCreate,\n    db: Session = Depends(get_db),\n):\n    \"\"\"Create a new effect preset.\"\"\"\n    from ..services import effects as effects_mod\n\n    try:\n        return effects_mod.create_preset(data, db)\n    except ValueError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n\n\n@router.put(\"/effects/presets/{preset_id}\", response_model=models.EffectPresetResponse)\nasync def update_effect_preset(\n    preset_id: str,\n    data: models.EffectPresetUpdate,\n    db: Session = Depends(get_db),\n):\n    \"\"\"Update an effect preset.\"\"\"\n    from ..services import effects as effects_mod\n\n    try:\n        result = effects_mod.update_preset(preset_id, data, db)\n        if not result:\n            raise HTTPException(status_code=404, detail=\"Preset not found\")\n        return result\n    except ValueError as e:\n        raise HTTPException(status_code=400, detail=str(e))","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/effects.py#L86-L122","documentation":"HTTP 400 raised by POST /effects/presets when effects_mod.create_preset() raises ValueError. The service raises ValueError in two cases: the effects_chain fails validate_effects_chain() (unknown type/out-of-range param/etc., message passed through), or a preset with the given name already exists (checked before insert and again on IntegrityError). The handler re-wraps the message into 400.","triggerScenarios":"Creating a preset whose effects_chain is invalid, or whose name duplicates an existing preset (built-in or user).","commonSituations":"Naming a new preset the same as an existing one; shipping a chain config built for an older effect registry; re-running a create after it partially succeeded.","solutions":["If the detail mentions 'already exists', pick a unique name or rename the conflicting preset first.","If the detail is a chain-validation message, fix the offending effect/param per the validator rules.","GET /effects/presets and check names client-side before submitting.","Validate the chain with the same rules as validate_effects_chain before posting."],"exampleFix":"// before\nawait fetch('/effects/presets', { method:'POST', body: JSON.stringify({ name, effects_chain }) });\n// after\nconst presets = await fetch('/effects/presets').then(r => r.json());\nif (presets.some(p => p.name === name)) { alert('Preset name already used'); return; }\nawait fetch('/effects/presets', { method:'POST', body: JSON.stringify({ name, effects_chain }) });","handlingStrategy":"validation","validationCode":"const presets = await fetch('/effects/presets').then(r => r.json());\nif (presets.some(p => p.name === name)) throw new Error('preset name already used');\n// plus run the same chain validation as error 94","typeGuard":"function isUniquePresetName(name, presets): boolean { return !presets.some(p => p.name === name); }","tryCatchPattern":"const r = await fetch('/effects/presets', { method:'POST', body: JSON.stringify(data) });\nif (r.status === 400) { const { detail } = await r.json(); /* 'already exists' or chain error */ }","preventionTips":["Check name uniqueness against the live presets list.","Validate the chain client-side before creating.","Pick descriptive unique names to avoid collisions."],"tags":["effects","http","validation","conflict","fastapi"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}