unslothai/unsloth · warning · ValueError

Delete a preset before saving another one

Error message

Delete a preset before saving another one

What it means

upsert_media_generation_preset() enforces a cap of _MAX_PRESETS custom presets per generation kind (image/video). Saving a NEW preset name when the stored list already has _MAX_PRESETS readable presets raises this; saving over an existing name (replacing) is always allowed, and unreadable/stale entries are filtered out by is_readable before counting.

Source

Thrown at studio/backend/utils/media_generation_preset_settings.py:82

            submitted = preserve_recovered(stored, submitted)
        updated = _with_unknown_preserved(
            stored,
            submitted,
        )
        upsert_app_settings({_setting_key(kind): updated})


def upsert_media_generation_preset(
    kind: MediaGenerationKind, preset: dict, is_readable: Callable[[dict], bool]
) -> None:
    from storage.studio_db import upsert_app_settings
    with _settings_lock:
        stored = _stored_settings(kind)
        presets = _custom_presets(stored)
        readable = [item for item in presets if is_readable(item)]
        replacing = any(item.get("name") == preset["name"] for item in readable)
        if not replacing and len(readable) >= _MAX_PRESETS:
            raise ValueError("Delete a preset before saving another one")
        stored["customPresets"] = [
            item for item in presets if item.get("name") != preset["name"]
        ] + [preset]
        upsert_app_settings({_setting_key(kind): stored})


def delete_media_generation_preset(kind: MediaGenerationKind, name: str) -> None:
    from storage.studio_db import upsert_app_settings
    with _settings_lock:
        stored = _stored_settings(kind)
        stored["customPresets"] = [
            item for item in _custom_presets(stored) if item.get("name") != name
        ]
        upsert_app_settings({_setting_key(kind): stored})

View on GitHub (pinned to 203007d190)

Solutions

  1. Delete an existing preset first via delete_media_generation_preset(kind, name), then save the new one
  2. Save over an existing name instead of creating a new entry — overwrites bypass the cap
  3. Raise _MAX_PRESETS in the module and restart, if a larger library is genuinely needed
  4. Prune presets whose backing models are gone (they stop counting once is_readable flags them unreadable)

Example fix

# before
upsert_media_generation_preset('image', {'name': 'preset-11'}, is_readable)
# ValueError: Delete a preset before saving another one

# after
delete_media_generation_preset('image', 'preset-3')
upsert_media_generation_preset('image', {'name': 'preset-11'}, is_readable)  # ok
Defensive patterns

Strategy: validation

Validate before calling

from utils.media_generation_preset_settings import _custom_presets, _stored_settings, _MAX_PRESETS

def can_save_preset(kind, name: str, is_readable) -> bool:
    readable = [p for p in _custom_presets(_stored_settings(kind)) if is_readable(p)]
    return any(p.get('name') == name for p in readable) or len(readable) < _MAX_PRESETS

Try / catch

try:
    upsert_media_generation_preset(kind, preset, is_readable)
except ValueError:
    prompt_user_to_delete_one(kind)  # then retry upsert

Prevention

When it happens

Trigger: Calling upsert_media_generation_preset(kind, preset, is_readable) where preset['name'] does not match any stored readable preset and len(readable) >= _MAX_PRESETS. The check runs under _settings_lock, so the count is race-free within one process.

Common situations: A user iterating on generation settings saves each variation as a new preset and hits the ceiling; preset entries pointing at deleted LoRAs/models keep counting until their is_readable flags them unreadable; teams sharing a settings DB accumulating presets.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/dc300beff2a32969. Report an issue: GitHub.