unslothai/unsloth · warning · HTTPException
'{config['output_dir']}' is the outputs folder itself, not a
Error message
'{config['output_dir']}' is the outputs folder itself, not a run inside it. Pick a name for this run. What it means
HTTP 400 on diffusion training start: the requested output_dir name sanitizes/resolves to the outputs ROOT directory itself (e.g. '.' or 'outputs' or './.'), not a run directory inside it. Writing there would place the adapter flat in the outputs folder where the is_dir()-filtered listings could never display it. The route compares Path(resolve_output_dir(output_dir)).resolve() against outputs_root().resolve() and rejects equality before spawning.
Source
Thrown at studio/backend/routes/training.py:2739
"Stop it before starting diffusion (Images) training."
),
)
except HTTPException:
raise
except Exception: # noqa: BLE001 -- backend import/health issue must not block a start
pass
# Resolve + contain the dataset and output paths BEFORE spawning: the trainer subprocess would otherwise resolve them relative to its own cwd.
config = body.model_dump()
try:
from utils.paths import outputs_root, resolve_output_dir
config["data_dir"] = str(_resolve_diffusion_data_dir(config["data_dir"]))
# A name that cleans away to nothing ("." / "outputs" / "./.") resolves to the outputs ROOT, where the trainer would write the adapter flat and the is_dir()-filtered listings could never see it.
root = outputs_root().resolve()
out_dir = resolve_output_dir(config["output_dir"])
if Path(out_dir).resolve() == root:
raise HTTPException(
status_code = 400,
detail = (
f"'{config['output_dir']}' is the outputs folder itself, not a run inside it. "
"Pick a name for this run."
),
)
config["output_dir"] = str(out_dir)
# The persistent conditioning cache is another trainer-written directory, so it gets the same containment. Blank/None means the in-memory cache, so it must not resolve to the outputs root.
cond_cache = str(config.get("cond_cache_dir") or "").strip()
cond_cache_dir = resolve_output_dir(cond_cache) if cond_cache else None
# Same collapse, but the cache has an honest "off" to fall back to: one flat safetensors per cached latent in the trained-models directory is never what was meant.
if cond_cache_dir is not None and Path(cond_cache_dir).resolve() == root:
cond_cache_dir = None
config["cond_cache_dir"] = str(cond_cache_dir) if cond_cache_dir is not None else None
except ValueError as e:
raise HTTPException(status_code = 400, detail = str(e))
# Validate the config BEFORE freeing resident GPU workloads, so a refused start never tears down the user's chat/Images model. service.start() re-runs this before spawn.View on GitHub (pinned to 203007d190)
Solutions
- Provide a real run name, e.g. output_dir='my-sdxl-run-1'.
- In UI/client code, treat an empty run name as a form error instead of sending '.'.
- Never pass the literal outputs root path as output_dir.
Example fix
// before
{"output_dir": ".", ...}
// after
{"output_dir": "sdxl-lora-run-1", ...} Defensive patterns
Strategy: validation
Validate before calling
function validRunName(name) {
const cleaned = (name ?? '').trim().replace(/\\.[\\/]+/g, '')
return cleaned !== '' && cleaned !== '.' && cleaned !== 'outputs' && !name.startsWith('/')
}
if (!validRunName(payload.output_dir)) throw new Error('Pick a real run name (not "." or "outputs")') Try / catch
try { await startDiffusionTraining(payload) } catch (e) { if (e.status === 400 && /outputs folder itself/.test(e.detail)) { payload.output_dir = `run-${Date.now()}`; return startDiffusionTraining(payload) } throw e } Prevention
- Require a non-empty run name in the UI form; never default to '.'.
- Treat output_dir as a run NAME, not a filesystem path.
- Reject '.', 'outputs', and empty values client-side before sending.
When it happens
Trigger: POST diffusion training start with output_dir='.', 'outputs', './.', or any name that cleans away to the outputs root.
Common situations: Clients defaulting output_dir to '.' when the user leaves the run-name field blank; hand-written config files with an empty or placeholder output name.
Related errors
- str(e)
- cond_cache_dir is not supported for the sdxl family: its tra
- Unknown model_kind '{model_kind}'. Expected one of {sorted(_
- Invalid base64 image data: {exc}
- Image is too large ({w}x{h}); maximum is {max_side}px per si
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/c79e4fc32dd0093c.
Report an issue: GitHub.