unslothai/unsloth · error · TypeError

Unsloth MLX: use_adapter must be None, True, False, or a str

Error message

Unsloth MLX: use_adapter must be None, True, False, or a string.

What it means

Thrown by _temporary_mlx_adapter_state in the MLX inference backend when the use_adapter argument is not one of the accepted values. The contextmanager routes a single request through the LoRA adapter or the base model, so it first validates use_adapter: None (keep current state), True (adapter), False (base), or a string (named adapter, which raises NotImplementedError instead). Anything else (e.g. an int, dict, or numpy bool) fails this TypeError before any adapter tree surgery happens.

Source

Thrown at studio/backend/core/inference/mlx_inference.py:60

            unsupported.append(path)
        else:
            adapters.append((path, module, base))
    return adapters, unsupported


@contextmanager
def _temporary_mlx_adapter_state(model, use_adapter):
    """Select base or adapter modules for one request, then restore the tree."""
    if use_adapter is None:
        yield
        return
    if isinstance(use_adapter, str):
        raise NotImplementedError(
            "Unsloth MLX: named adapter selection is not supported; use True for "
            "the loaded adapter or False for the base model."
        )
    if use_adapter is not True and use_adapter is not False:
        raise TypeError("Unsloth MLX: use_adapter must be None, True, False, or a string.")

    adapters, unsupported = _mlx_adapter_modules(model)
    if use_adapter is True:
        if not adapters and not unsupported:
            logger.warning("MLX adapter requested, but the active model has no adapter layers")
        yield
        return
    if unsupported:
        raise RuntimeError(
            "Unsloth MLX: cannot disable adapter layers without their base modules: "
            + ", ".join(unsupported[:5])
        )
    if not adapters:
        yield
        return

    from mlx.utils import tree_unflatten

View on GitHub (pinned to 203007d190)

Solutions

  1. Pass a strict Python bool: use_adapter=True to use the loaded adapter, use_adapter=False for the base model, or use_adapter=None to keep the current state.
  2. If the value comes from JSON/API input, coerce or validate it at the request boundary (bool(value) is not enough — explicitly accept only true/false/null/strings).
  3. If you meant to select an adapter by name, note strings raise NotImplementedError; load the desired adapter as the active model instead.

Example fix

# before
backend.stream_response(messages, use_adapter=1)

# after
backend.stream_response(messages, use_adapter=True)
Defensive patterns

Strategy: type-guard

Validate before calling

def is_valid_use_adapter(v) -> bool:
    return v is None or isinstance(v, bool) or isinstance(v, str)

Type guard

def is_use_adapter(value: object) -> TypeGuard[None | bool | str]:
    return value is None or isinstance(value, bool) or isinstance(value, str)

Try / catch

try:
    with _temporary_mlx_adapter_state(model, use_adapter):
        generate()
except TypeError as e:
    if 'use_adapter' in str(e):
        raise ValueError(f'bad use_adapter={use_adapter!r}') from e
    raise

Prevention

When it happens

Trigger: Calling the MLX generation/streaming API with use_adapter set to a non-boolean, non-None, non-string value — e.g. use_adapter=1, use_adapter=np.True_, use_adapter={'name': 'my-lora'}, or a value parsed from JSON that arrived as a number. The check fires immediately upon entering the context manager, before any model work.

Common situations: JSON request payloads where the client sent use_adapter: 1 instead of true; passing numpy/torch booleans from a training pipeline into the inference API; a config schema that defaults use_adapter to 0/''.

Related errors


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