invoke-ai/InvokeAI · error · HTTPException
Not authorized to modify this style preset
Error message
Not authorized to modify this style preset
What it means
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.
Source
Thrown at invokeai/app/api/routers/style_presets.py:65
return
if record.type == PresetType.Default:
return
if record.is_public:
return
if record.user_id == current_user.user_id:
return
raise HTTPException(status_code=403, detail="Not authorized to access this style preset")
def _assert_preset_write(record: StylePresetRecordDTO, current_user: TokenData) -> None:
"""Allow write access only for admin or owner. Defaults are immutable for non-admins."""
if current_user.is_admin:
return
if record.type == PresetType.Default:
raise HTTPException(status_code=403, detail="Default style presets cannot be modified")
if record.user_id == current_user.user_id:
return
raise HTTPException(status_code=403, detail="Not authorized to modify this style preset")
def _load_record_or_404(style_preset_id: str) -> StylePresetRecordDTO:
try:
return ApiDependencies.invoker.services.style_preset_records.get(style_preset_id)
except StylePresetNotFoundError:
raise HTTPException(status_code=404, detail="Style preset not found")
@style_presets_router.get(
"/i/{style_preset_id}",
operation_id="get_style_preset",
responses={
200: {"model": StylePresetRecordWithImage},
},
)
def get_style_preset(
current_user: CurrentUserOrDefault,View on GitHub (pinned to 0b6a024f2f)
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
Example fix
// before
await api.put(`/style_presets/i/${id}`, payload); // 403 if not owner
// after
const preset = await api.get(`/style_presets/i/${id}`);
if (currentUser.is_admin || preset.user_id === currentUser.id) {
await api.put(`/style_presets/i/${id}`, payload);
} else {
const copy = await api.post('/style_presets/', { ...preset.data, name: preset.data.name + ' (copy)' });
await api.put(`/style_presets/i/${copy.data.id}`, payload);
} Defensive patterns
Strategy: validation
Validate before calling
const preset = (await api.get(`/style_presets/i/${id}`)).data;
if (!currentUser.is_admin && preset.user_id !== currentUser.id) {
throw new Error('Not the owner: fork the preset before modifying it');
} Type guard
function canWritePreset(preset, user) {
return user.is_admin === true || preset.user_id === user.user_id;
} Try / catch
try {
await api.delete(`/style_presets/i/${id}`);
} catch (e) {
if (e.response?.status === 403) {
console.warn('Not owner or not admin; request the owner or fork first');
return;
}
throw e;
} Prevention
- 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
When it happens
Trigger: PUT/DELETE on a public-but-foreign preset, or on another user's private preset, with a non-admin token.
Common situations: 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).
Related errors
- Not authorized to delete this board
- Not authorized to access this style preset
- Default style presets cannot be modified
- Not authorized to modify this board
- Not authorized to move this image
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/9a5e60f036b69e17.
Report an issue: GitHub.