unslothai/unsloth · error · ValueError
save_steps is not supported for {resolved_family}: its train
Error message
save_steps is not supported for {resolved_family}: its trainer writes no checkpoint bundle. Leave it at 0; the adapter is still saved at the end. What it means
Raised when save_steps is non-zero for a family in CHECKPOINTLESS_FAMILIES (the H3 loop). That trainer writes no intermediate checkpoint bundle, so requesting periodic saves was previously accepted silently and the caller got no checkpoints — discovered only after an expensive run. Validation refuses it up front; note the final adapter is still saved at the end regardless.
Source
Thrown at studio/backend/core/training/diffusion_train_common.py:1084
resume_from_checkpoint = (
str(self.resume_from_checkpoint).strip()
if self.resume_from_checkpoint is not None
else ""
) or None
# The H3 loop does not checkpoint: it neither writes a resume bundle nor restores one.
# Accepting these two silently was the dangerous part -- a caller handing over a resume
# bundle got a FRESH optimization that then overwrote the outputs it was meant to
# continue, and one asking for periodic saves got none, both discovered only after an
# expensive run. Refuse in validation, where it costs nothing, until the loop supports it.
if resolved_family in CHECKPOINTLESS_FAMILIES:
if resume_from_checkpoint:
raise ValueError(
f"resume_from_checkpoint is not supported for {resolved_family}: its trainer "
f"writes no checkpoint bundle, so there is nothing to continue from and the "
f"run would silently start over and overwrite its output. Start a fresh run."
)
if save_steps:
raise ValueError(
f"save_steps is not supported for {resolved_family}: its trainer writes no "
f"checkpoint bundle. Leave it at 0; the adapter is still saved at the end."
)
try:
ema_decay = float(self.ema_decay or 0.0)
except (TypeError, ValueError) as exc:
raise ValueError(f"ema_decay must be a number, got {self.ema_decay!r}") from exc
# decay = 1.0 would freeze the shadow at its init forever; the update is shadow * decay + param * (1 - decay), so valid decays live in [0, 1).
if not 0.0 <= ema_decay < 1.0:
raise ValueError("ema_decay must be in [0, 1); 0 disables the EMA adapter")
# A blank cond_cache_dir (the Studio default when unset) means "off", not cwd.
cond_cache_dir = (
str(self.cond_cache_dir).strip() if self.cond_cache_dir is not None else ""
) or None
compile_transformer = str(self.compile_transformer or "auto").strip().lower()
if compile_transformer not in ("off", "on", "auto"):
raise ValueError("compile_transformer must be one of off / on / auto")
base_precision = str(self.base_precision or "nf4").strip().lower()View on GitHub (pinned to 203007d190)
Solutions
- Leave save_steps at 0 for this family — the adapter is still saved when the run finishes.
- Remove save cadence from shared config templates, or make it per-family.
- If you need mid-run checkpoints, switch to a family whose trainer supports them.
Example fix
# before config = TrainConfig(base_model='h3-family-model', save_steps=500) # after config = TrainConfig(base_model='h3-family-model', save_steps=0) # final adapter still saved
Defensive patterns
Strategy: validation
Validate before calling
CHECKPOINTLESS_FAMILIES = {...}
def check_save_steps_for_family(family, save_steps) -> int:
n = int(save_steps or 0)
if family in CHECKPOINTLESS_FAMILIES and n:
raise ValueError(f"family {family} writes no checkpoints; save_steps must stay 0")
return n Type guard
def family_supports_periodic_checkpoints(family) -> bool:
return family not in CHECKPOINTLESS_FAMILIES Try / catch
try:
session.submit_training(config)
except ValueError as e:
if "save_steps is not supported" in str(e):
config.save_steps = 0 # final adapter is still saved; nothing else to do
session.submit_training(config)
else:
raise Prevention
- Keep save cadence out of shared config templates, or make it per-family.
- Remember the final adapter is always saved — periodic steps are unnecessary for these families.
- Validate checkpoint knobs against the family's capability before submission.
When it happens
Trigger: Submitting save_steps > 0 together with a checkpointless family. Usually a shared config template with a default save cadence (e.g. save_steps=500) applied to every family.
Common situations: One global training config reused across base models; UI presets that include a save cadence; migration from checkpoint-capable families where periodic saves worked.
Related errors
- save_steps / save_total_limit must be whole numbers, got {se
- save_steps must be >= 0 (0 disables periodic checkpoints)
- save_total_limit must be >= 0 (0 keeps every checkpoint)
- gradient_accumulation_steps must be >= 1
- lora_rank must be >= 1
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/131ce0be5b817ff1.
Report an issue: GitHub.