unslothai/unsloth · warning · HTTPException

cond_cache_dir is not supported for the sdxl family: its tra

Error message

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, z-image, krea-2), which reuses conditioning across runs.

What it means

HTTP 400 on diffusion training start: the request sets cond_cache_dir (persistent conditioning/latent cache) but the RESOLVED model family is 'sdxl', whose trainer uses a per-run in-memory latent cache and would silently ignore the persistent one. The check uses normalized_cfg.resolved_family (what the trainer will actually run), not the raw request field, so aliases that resolve to SDXL are caught too. The error lists the DiT families that do support it (flux.1, flux.2-klein, flux.2-dev, qwen-image, z-image, krea-2).

Source

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

        # 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, "
                "z-image, krea-2), which reuses conditioning across runs."
            ),
        )

    # Same rule for the MiniMax-H3 trainer's own restrictions, which are config-only and so
    # answerable here: a batch > 1, a non-bf16 precision, a weighting scheme, a compile
    # request or a conditioning-cache directory used to reach the worker and 400 there, with
    # the user's resident models already evicted for a run that never started.
    from core.training.diffusion_train_common import h3_train_unsupported_reason

    _h3_reason = h3_train_unsupported_reason(normalized_cfg)
    if _h3_reason:
        raise HTTPException(status_code = 400, detail = _h3_reason)

View on GitHub (pinned to 203007d190)

Solutions

  1. Remove/omit cond_cache_dir for SDXL runs — its latent cache is automatic and in-memory.
  2. Or switch the model to a DiT family (flux.1, flux.2-klein, flux.2-dev, qwen-image, z-image, krea-2) to reuse conditioning across runs.
  3. Clear family-specific fields in the client whenever the resolved model family changes.

Example fix

// before
{"model": "sd-xl-base", "cond_cache_dir": "cond-cache/", ...}
// after (sdxl: omit it)
{"model": "sd-xl-base", ...}
// after (keep the cache: use a DiT family)
{"model": "flux.1-dev", "cond_cache_dir": "cond-cache/", ...}
Defensive patterns

Strategy: validation

Validate before calling

const SDXL_HINTS = /sdxl|sd-xl|sd_xl/i
function isSdxl(model) { return SDXL_HINTS.test(model) }
if (config.cond_cache_dir && isSdxl(config.model)) {
  delete config.cond_cache_dir // sdxl uses a per-run in-memory latent cache
}

Type guard

function supportsCondCache(resolvedFamily) {
  return ['flux.1', 'flux.2-klein', 'flux.2-dev', 'qwen-image', 'z-image', 'krea-2']
    .includes(resolvedFamily)
}

Try / catch

try { await startDiffusionTraining(payload) } catch (e) { if (e.status === 400 && /cond_cache_dir is not supported for the sdxl family/.test(e.detail)) { delete payload.cond_cache_dir; return startDiffusionTraining(payload) } throw e }

Prevention

When it happens

Trigger: POST diffusion training start with cond_cache_dir set and a model that resolves to the sdxl family (including aliased or shorthand model names that resolve to SDXL).

Common situations: Copy-pasting a Flux config (which benefits from the conditioning cache across runs) to an SDXL run; UI state retaining the cache field when the user switches model family.

Related errors


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