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, soView on GitHub (pinned to 203007d190)
Solutions
- Supply both values: '--control-vector-layer-range 10 40' — START and END as two separate tokens.
- Check the error message for which flag (two_value_flag) is incomplete, then find its missing second value in your config.
- 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
- Memorize the two-value flags (layer ranges take START END).
- When editing configs, remove both values with the flag.
- Validate the pair client-side before save when the flag name is known.
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
- extra llama-server args cannot contain a bare value ('{token
- llama-server does not accept the spaces around '{token[:64]}
- llama-server does not read an attached value: write '{flag}'
- too many extra llama-server args (limit {MAX_EXTRA_ARG_TOKEN
- extra llama-server args are too large (limit {limit} bytes)
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/fd56166d636092c1.
Report an issue: GitHub.