{"record":{"id":"a1cc1220b7e04590","repo":"jamiepine/voicebox","slug":"exception-message-from-update-preset-valueerror","errorCode":null,"errorMessage":"{exception message from update_preset (ValueError)}","messagePattern":"\\{exception message from update_preset \\(ValueError\\)\\}","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"backend/routes/effects.py","lineNumber":122,"sourceCode":"        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))\n\n\n@router.delete(\"/effects/presets/{preset_id}\")\nasync def delete_effect_preset(preset_id: str, db: Session = Depends(get_db)):\n    \"\"\"Delete a user effect preset.\"\"\"\n    from ..services import effects as effects_mod\n\n    try:\n        if not effects_mod.delete_preset(preset_id, db):\n            raise HTTPException(status_code=404, detail=\"Preset not found\")\n        return {\"status\": \"deleted\"}\n    except ValueError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n\n\n@router.get(\n    \"/generations/{generation_id}/versions\",\n    response_model=list[models.GenerationVersionResponse],","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/effects.py#L104-L140","documentation":"HTTP 400 raised by PUT /effects/presets/{preset_id} when effects_mod.update_preset() raises ValueError. The service raises ValueError in two cases: the preset is built-in (is_builtin true -> 'Cannot modify built-in presets'), or the supplied effects_chain fails validate_effects_chain() (unknown type/out-of-range param, message passed through). The handler re-wraps the message into 400.","triggerScenarios":"PUTting to a built-in preset, or supplying an effects_chain that violates the validator rules.","commonSituations":"Editing a shipped built-in preset instead of a user one; sending a chain with a typo'd effect name or out-of-range param; UI not disabling edit for built-ins.","solutions":["If the detail is 'Cannot modify built-in presets', target a user-created preset or create a new one.","If the detail is a chain-validation message, fix the named effect/param per the validator.","Disable edit controls for presets where is_builtin is true.","Validate the chain client-side with the same rules before submitting."],"exampleFix":"// before\nawait fetch(`/effects/presets/${id}`, { method:'PUT', body: JSON.stringify({ effects_chain }) });\n// after\nif (preset.is_builtin) { alert('Duplicate the built-in preset to edit it'); return; }\nawait fetch(`/effects/presets/${id}`, { method:'PUT', body: JSON.stringify({ effects_chain }) });","handlingStrategy":"validation","validationCode":"if (preset.is_builtin) throw new Error('cannot modify built-in preset');\n// plus run the same chain validation as error 94","typeGuard":"function isBuiltinPreset(p): p is { is_builtin: true } { return p?.is_builtin === true; }","tryCatchPattern":"const r = await fetch(`/effects/presets/${id}`, { method:'PUT', body: JSON.stringify(patch) });\nif (r.status === 400) { const { detail } = await r.json(); /* 'Cannot modify built-in presets' or chain error */ }","preventionTips":["Disable editing for presets where is_builtin is true.","Duplicate a built-in preset to a user preset to customize it.","Validate the chain client-side before submitting."],"tags":["effects","http","validation","conflict","fastapi"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}