{"record":{"id":"9a5e60f036b69e17","repo":"invoke-ai/InvokeAI","slug":"not-authorized-to-modify-this-style-preset","errorCode":null,"errorMessage":"Not authorized to modify this style preset","messagePattern":"Not authorized to modify this style preset","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"invokeai/app/api/routers/style_presets.py","lineNumber":65,"sourceCode":"        return\n    if record.type == PresetType.Default:\n        return\n    if record.is_public:\n        return\n    if record.user_id == current_user.user_id:\n        return\n    raise HTTPException(status_code=403, detail=\"Not authorized to access this style preset\")\n\n\ndef _assert_preset_write(record: StylePresetRecordDTO, current_user: TokenData) -> None:\n    \"\"\"Allow write access only for admin or owner. Defaults are immutable for non-admins.\"\"\"\n    if current_user.is_admin:\n        return\n    if record.type == PresetType.Default:\n        raise HTTPException(status_code=403, detail=\"Default style presets cannot be modified\")\n    if record.user_id == current_user.user_id:\n        return\n    raise HTTPException(status_code=403, detail=\"Not authorized to modify this style preset\")\n\n\ndef _load_record_or_404(style_preset_id: str) -> StylePresetRecordDTO:\n    try:\n        return ApiDependencies.invoker.services.style_preset_records.get(style_preset_id)\n    except StylePresetNotFoundError:\n        raise HTTPException(status_code=404, detail=\"Style preset not found\")\n\n\n@style_presets_router.get(\n    \"/i/{style_preset_id}\",\n    operation_id=\"get_style_preset\",\n    responses={\n        200: {\"model\": StylePresetRecordWithImage},\n    },\n)\ndef get_style_preset(\n    current_user: CurrentUserOrDefault,","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/api/routers/style_presets.py#L47-L83","documentation":"This HTTP 403 is the final check in _assert_preset_write: a non-admin user attempting to update or delete a non-default preset that they do not own. Only the owner (matching user_id) or an admin may modify a style preset.","triggerScenarios":"PUT/DELETE on a public-but-foreign preset, or on another user's private preset, with a non-admin token.","commonSituations":"Assuming public presets are editable by everyone (public grants read, not write); shared instances where colleagues try to edit each other's presets; stale tokens after user re-creation (different user_id, same username).","solutions":["Fork the preset: create your own copy and edit that","Have the owner make the change, or use an admin account","Verify the token's user_id actually matches the preset owner (user re-creation changes IDs)","In bulk tooling, filter writes to presets where preset.user_id === currentUser.id"],"exampleFix":"// before\nawait api.put(`/style_presets/i/${id}`, payload); // 403 if not owner\n// after\nconst preset = await api.get(`/style_presets/i/${id}`);\nif (currentUser.is_admin || preset.user_id === currentUser.id) {\n  await api.put(`/style_presets/i/${id}`, payload);\n} else {\n  const copy = await api.post('/style_presets/', { ...preset.data, name: preset.data.name + ' (copy)' });\n  await api.put(`/style_presets/i/${copy.data.id}`, payload);\n}","handlingStrategy":"validation","validationCode":"const preset = (await api.get(`/style_presets/i/${id}`)).data;\nif (!currentUser.is_admin && preset.user_id !== currentUser.id) {\n  throw new Error('Not the owner: fork the preset before modifying it');\n}","typeGuard":"function canWritePreset(preset, user) {\n  return user.is_admin === true || preset.user_id === user.user_id;\n}","tryCatchPattern":"try {\n  await api.delete(`/style_presets/i/${id}`);\n} catch (e) {\n  if (e.response?.status === 403) {\n    console.warn('Not owner or not admin; request the owner or fork first');\n    return;\n  }\n  throw e;\n}","preventionTips":["Remember: public grants read access only, never write","Compare preset.user_id to your token's user_id before writes","Re-verify ownership after user accounts are re-created (IDs change)","In shared teams, agree on who owns shared presets or use an admin for edits"],"tags":["http-403","authorization","style-presets","ownership"],"backgroundTag":"insufficient-permissions","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}