unslothai/unsloth · warning · ValueError

Preset name is reserved or empty

Error message

Preset name is reserved or empty

What it means

Pydantic validation failure (surfaces as HTTP 422 from FastAPI) raised by the field_validator on MediaGenerationPreset.name. The validator strips whitespace and rejects the result when it is empty or exactly the reserved name 'Default'. Pydantic wraps the ValueError into the 422 response body under the field path; it never reaches your handler code.

Source

Thrown at studio/backend/routes/settings.py:165

    height: int = Field(default = 512, ge = 32, le = 2048)
    durationSeconds: float = Field(default = 3, gt = 0, le = 3600)
    steps: int = Field(default = 8, ge = 1, le = 100)
    guidance: float = Field(default = 1, ge = 0, le = 20)
    flowShift: Optional[float] = Field(default = None, gt = 0, le = 100)
    audioFlowShift: Optional[float] = Field(default = None, gt = 0, le = 100)


class MediaGenerationPreset(BaseModel):
    model_config = ConfigDict(extra = "forbid")

    name: str = Field(..., min_length = 1, max_length = 80)

    @field_validator("name")
    @classmethod
    def normalize_name(cls, value: str) -> str:
        name = value.strip()
        if not name or name == "Default":
            raise ValueError("Preset name is reserved or empty")
        return name


class ImageGenerationPreset(MediaGenerationPreset):
    params: ImageGenerationPresetParams


class VideoGenerationPreset(MediaGenerationPreset):
    params: VideoGenerationPresetParams


class MediaGenerationPresetState(BaseModel):
    """A saved generation recipe and the selection that owns it.

    Model-load options are deliberately not here: they take effect only on a reload, they follow
    the hardware and the checkpoint rather than the recipe, and the resident build already reports
    them, so a second stored copy would only ever compete with it.
    """

View on GitHub (pinned to 203007d190)

Solutions

  1. Choose a non-empty, non-'Default' name (after trimming) and resubmit.
  2. Add client-side validation mirroring the rule: strip, reject empty and exact 'Default', max 80 chars.
  3. If you need a default preset, use the built-in one rather than saving a custom preset named 'Default'.

Example fix

// before
await api.put('/settings/generation-presets/image/custom', { name: '  ', params }); // 422

// after
const name = rawName.trim();
if (!name || name === 'Default') throw new Error('Name must be non-empty and not "Default"');
await api.put('/settings/generation-presets/image/custom', { name, params });
Defensive patterns

Strategy: validation

Validate before calling

function validPresetName(raw: string): boolean {
  const name = raw.trim();
  return name.length >= 1 && name.length <= 80 && name !== 'Default';
}

Type guard

function isValidPresetName(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length >= 1 && v.trim().length <= 80 && v.trim() !== 'Default';
}

Try / catch

try { await api.put(presetUrl, payload); }
catch (e) {
  if (e.status === 422) { markNameInvalid(extractFieldError(e, 'name')); return; }
  throw e;
}

Prevention

When it happens

Trigger: PUT /settings/generation-presets/image|video/custom with name "" , " ", or "Default" / "default " — note only the exact case-sensitive 'Default' after strip is reserved, so 'DEFAULT' passes.

Common situations: Frontend form pre-filling 'Default' as a placeholder and submitting unchanged; user entering only spaces; copying a preset and forgetting to rename it; name submitted after a trim that left an empty string.

Related errors


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