unslothai/unsloth · warning · HTTPException

str(e)

Error message

str(e)

What it means

HTTP 400 with the raw ValueError message from the path-resolution block of the diffusion start route: _resolve_diffusion_data_dir / resolve_output_dir raise ValueError when the dataset dir or output dir fails containment/normalization rules (e.g. escapes the workspace via '..' or absolute paths pointing outside allowed roots, or malformed names). The detail is the exception's own text.

Source

Thrown at studio/backend/routes/training.py:2755

        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.
    from core.training.diffusion_lora_trainer import _config_from_dict

    try:
        normalized_cfg = _config_from_dict(config).normalized()
    except ValueError as e:
        raise HTTPException(status_code = 400, detail = str(e))

    # Only the DiT trainer reads cond_cache_dir; the SDXL trainer's latent cache is per-process
    # and in-memory. Checked against the RESOLVED family, not the request field.
    if cond_cache and normalized_cfg.resolved_family == "sdxl":
        raise HTTPException(
            status_code = 400,
            detail = (
                "cond_cache_dir is not supported for the sdxl family: its trainer uses a "
                "per-run in-memory latent cache and would ignore the persistent one. Omit it, "
                "or train a DiT family (flux.1, flux.2-klein, flux.2-dev, qwen-image, "

View on GitHub (pinned to 203007d190)

Solutions

  1. Read the detail text — it names which path and which rule failed.
  2. Use a plain run name for output_dir and a dataset dir under the workspace; avoid '..' and absolute paths.
  3. If an external dataset location is required, import/copy it into the workspace dataset area first.

Example fix

// before
{"data_dir": "/mnt/nas/datasets/cats", "output_dir": "../runs/x"}
// after
{"data_dir": "datasets/cats", "output_dir": "cats-lora-run"}
Defensive patterns

Strategy: validation

Validate before calling

function assertSafeRelativePath(p, field) {
  if (!p || path.isAbsolute(p) || p.split(/[\\/\\]/).includes('..')) {
    throw new Error(`${field} must be a workspace-relative path without '..' segments`)
  }
}
assertSafeRelativePath(config.data_dir, 'data_dir')
assertSafeRelativePath(config.output_dir, 'output_dir')

Try / catch

try { await startDiffusionTraining(payload) } catch (e) { if (e.status === 400 && e.detail) { showFieldError(e.detail); return } throw e } // detail names the offending path and rule

Prevention

When it happens

Trigger: POST diffusion training start with data_dir or output_dir containing traversal segments ('../'), disallowed absolute paths, or otherwise unresolvable values under utils.paths resolution rules.

Common situations: Config files authored on another machine with absolute paths; users trying to write outputs to an arbitrary filesystem location instead of a run name; '..'-style relative paths copied from a shell workflow.

Related errors


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