unslothai/unsloth · warning · HTTPException
Training images cannot be changed while diffusion training i
Error message
Training images cannot be changed while diffusion training is active. Stop the run before uploading, importing, editing captions, or deleting images.
What it means
HTTP 409 from _require_diffusion_dataset_mutable(): the diffusion trainer re-opens dataset images during its loop, so any dataset mutation (upload, import, caption edit, delete) while a diffusion run is active would make the run nondeterministic or crash it with FileNotFoundError mid-step. The guard deliberately fails open — if the training service cannot be imported/state is unknowable, mutations are allowed — matching the start interlock.
Source
Thrown at studio/backend/routes/training.py:2505
except TrainingActiveError as exc:
raise _DiffusionStartInFlight(
"A diffusion (Images) LoRA training job is already running. "
"Stop it before starting an LLM training run."
) from exc
try:
yield
finally:
cm.__exit__(None, None, None)
def _require_diffusion_dataset_mutable() -> None:
"""Reject a dataset mutation while a diffusion run is active.
The trainer re-opens dataset images during the loop, so mutating underneath it makes the run
nondeterministic or raises a FileNotFoundError mid-step. Fails open (a service-import failure
never blocks a mutation on an unknowable state), matching the start interlock."""
if _diffusion_training_active():
raise HTTPException(
status_code = 409,
detail = (
"Training images cannot be changed while diffusion training is active. "
"Stop the run before uploading, importing, editing captions, or deleting images."
),
)
def diffusion_dataset_interlock():
"""Dependency holding the dataset interlock for a whole mutating request.
The check above only covers the instant it runs: every one of these endpoints then hands its
filesystem work to a thread, and a ``/diffusion/start`` reserving in that gap would move
captions or images underneath the preflight or the running trainer. As a yield dependency the
registration spans the endpoint, so ``reserve()`` sees it and refuses instead. Fails open on an
import error, like the check it replaces."""
try:
from core.training.diffusion_training_service import (View on GitHub (pinned to 203007d190)
Solutions
- Stop the diffusion training run and wait for it to finish (poll /training/status).
- Retry the mutation once the run is idle.
- Queue dataset edits client-side and flush them when no run is active.
Defensive patterns
Strategy: validation
Validate before calling
const active = await get('/training/diffusion/status').catch(() => null)
if (active?.is_running) throw new Error('Stop the diffusion run before mutating training images')
await mutateDataset(...) Try / catch
try { await uploadDatasetImage(file) } catch (e) { if (e.status === 409 && /cannot be changed while diffusion training/.test(e.detail)) { queueForLater(file); return } throw e } Prevention
- Disable dataset edit controls in the UI while a diffusion run is active.
- Queue mutations client-side and flush the queue when training is idle.
- Prepare datasets fully before starting a long diffusion run.
When it happens
Trigger: Calling any image dataset mutation endpoint (upload, import, caption edit, delete) while a diffusion (Images) training run is active, once the request enters the diffusion_dataset_interlock dependency.
Common situations: Users preparing the next dataset while a long SDXL/Flux LoRA run is going; automation scripts that upload images on a schedule regardless of training state.
Related errors
- str(exc)
- An LLM training job is already running. Stop it before start
- Cannot start diffusion (Images) training over the API while
- Unknown model_kind '{model_kind}'. Expected one of {sorted(_
- Invalid base64 image data: {exc}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/77bf1695b59d2a5d.
Report an issue: GitHub.