unslothai/unsloth · error · ValueError

llama-server flag '{two_value_flag}' takes two values

Error message

llama-server flag '{two_value_flag}' takes two values

What it means

ValueError from llama_server_args.py:323 — while processing a new flag token, pending_two_value > 0, meaning the previous two-value flag (e.g. --control-vector-layer-range START END, or a range-like pair) has so far received only its FIRST value and a new flag appears instead of the second. The module knows this arity for certain (unlike ordinary flags), so it enforces it: llama-server would exit on the incomplete option at spawn time, a failed load instead of a 400.

Source

Thrown at studio/backend/core/inference/llama_server_args.py:323

            # llama.cpp looks the WHOLE token up in its option map, folding only the
            # underscore spelling, so "--top-k=20" is not "--top-k" with a value: it
            # is an argument it has never heard of. Measured on b10342 and b10360,
            # where --top-k=20, --ctx-size=4096 and --flash-attn=on each exit with
            # "error: invalid argument". Accepting the GNU spelling here meant the
            # switch tore down the resident model and the child then refused to
            # start, so it is refused while it is still a 400 with somewhere to go.
            # Splitting it here would be a guess: for a switch the value is not one,
            # and this module cannot know an ordinary flag's arity.
            value = token.partition("=")[2]
            raise ValueError(
                f"llama-server does not read an attached value: write '{flag}' and "
                f"'{value[:32]}' as two separate arguments, not '{token[:64]}'"
            )
        else:
            # Its own value when attached, otherwise the tokens that follow.
            attached = _value_is_attached(token, flag)
            if pending_two_value > 0:
                raise ValueError(f"llama-server flag '{two_value_flag}' takes two values")
            # An attached value is ONE of the two, not the whole option:
            # "--control-vector-layer-range=1" still owes its END, and
            # llama-server exits on the incomplete option.
            if flag in _TWO_VALUE_FLAGS:
                pending_values = 1 if attached else 2
                pending_two_value = pending_values
            elif flag in _OPTIONAL_SECOND_VALUE_FLAGS:
                # Allowed, not owed: pending_two_value stays 0, so nothing here
                # insists on the second token.
                pending_values = 1 if attached else 2
                pending_two_value = 0
            else:
                pending_values = 0 if attached else 1
                pending_two_value = 0
            two_value_flag = flag
        out.append(token)
    if pending_two_value > 0:
        # Only this shape is checkable: an ordinary flag's arity is unknown here, so

View on GitHub (pinned to 203007d190)

Solutions

  1. Supply both values: '--control-vector-layer-range 10 40' — START and END as two separate tokens.
  2. Check the error message for which flag (two_value_flag) is incomplete, then find its missing second value in your config.
  3. When programmatically emitting these flags, assert len(values) == 2 for known two-value flags before submit.

Example fix

# before
extra_args = ["--control-vector-layer-range", "10", "--top-k", "40"]

# after
extra_args = ["--control-vector-layer-range", "10", "40", "--top-k", "40"]
Defensive patterns

Strategy: validation

Validate before calling

TWO_VALUE = {"--control-vector-layer-range"}  # mirror _TWO_VALUE_FLAGS
def complete_two_value_flags(tokens):
    i = 0
    while i < len(tokens):
        f = tokens[i]
        if f in TWO_VALUE and (i + 2 >= len(tokens) or tokens[i+2].startswith('-')):
            return False
        i += 1
    return True

Type guard

def two_value_flags_complete(tokens) -> bool:
    return complete_two_value_flags(tokens)

Try / catch

try:
    validate_extra_args(args)
except ValueError as e:
    if "takes two values" in str(e):
        raise HTTPException(400, "supply START and END for the named flag")
    raise

Prevention

When it happens

Trigger: '--control-vector-layer-range 10' followed by another flag (or end of a sub-list): the flag owes two values, only one is present, and the walk hits the next '--something' token while pending_two_value is still 1.

Common situations: Truncating or hand-editing a stored args list and dropping the END value; splitting a quoted command so the second value lands elsewhere; forgetting that layer-range takes START and END, not a single number.

Related errors


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