{"record":{"id":"cd6c973f635438dc","repo":"jamiepine/voicebox","slug":"preset-not-found","errorCode":null,"errorMessage":"Preset not found","messagePattern":"Preset not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/routes/effects.py","lineNumber":89,"sourceCode":"    return models.AvailableEffectsResponse(effects=[models.AvailableEffect(**e) for e in _get_effects()])\n\n\n@router.get(\"/effects/presets\", response_model=list[models.EffectPresetResponse])\nasync def list_effect_presets(db: Session = Depends(get_db)):\n    \"\"\"List all effect presets (built-in + user-created).\"\"\"\n    from ..services import effects as effects_mod\n\n    return effects_mod.list_presets(db)\n\n\n@router.get(\"/effects/presets/{preset_id}\", response_model=models.EffectPresetResponse)\nasync def get_effect_preset(preset_id: str, db: Session = Depends(get_db)):\n    \"\"\"Get a specific effect preset.\"\"\"\n    from ..services import effects as effects_mod\n\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)","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/effects.py#L71-L107","documentation":"HTTP 404 raised by GET /effects/presets/{preset_id} when effects_mod.get_preset() returns None, i.e. no EffectPreset row matches the preset_id (built-in or user). The handler raises 404 'Preset not found'. This is a pure lookup miss on the presets table.","triggerScenarios":"GET /effects/presets/{preset_id} with an ID that was never created, was deleted, or is malformed.","commonSituations":"Referencing a user preset that was deleted; storing a preset_id across sessions without refreshing; typo or copy-paste error in the ID.","solutions":["GET /effects/presets to list valid preset IDs before referencing one.","On 404, refresh the presets list and fall back to a default/built-in preset.","Do not cache preset_ids long-term; they can be deleted by the user."],"exampleFix":"// before\nconst p = await fetch(`/effects/presets/${id}`).then(r => r.json());\n// after\nconst r = await fetch(`/effects/presets/${id}`);\nif (r.status === 404) { const all = await fetch('/effects/presets').then(r => r.json()); return all[0]; }\nreturn r.json();","handlingStrategy":"validation","validationCode":"const presets = await fetch('/effects/presets').then(r => r.json());\nif (!presets.some(p => p.id === presetId)) throw new Error('preset missing');","typeGuard":"function isPresetList(v): v is Array<{ id: string }> { return Array.isArray(v) && v.every(p => typeof p?.id === 'string'); }","tryCatchPattern":"const r = await fetch(`/effects/presets/${id}`);\nif (r.status === 404) { const all = await fetch('/effects/presets').then(r => r.json()); return all[0]; }","preventionTips":["Source preset IDs from a fresh presets list.","Fall back to a built-in preset on 404.","Do not cache preset IDs long-term."],"tags":["effects","http","not-found","fastapi"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}