{"record":{"id":"fd56166d636092c1","repo":"unslothai/unsloth","slug":"llama-server-flag-two-value-flag-takes-two-val","errorCode":null,"errorMessage":"llama-server flag '{two_value_flag}' takes two values","messagePattern":"llama-server flag '(.+?)' takes two values","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/llama_server_args.py","lineNumber":323,"sourceCode":"            # llama.cpp looks the WHOLE token up in its option map, folding only the\n            # underscore spelling, so \"--top-k=20\" is not \"--top-k\" with a value: it\n            # is an argument it has never heard of. Measured on b10342 and b10360,\n            # where --top-k=20, --ctx-size=4096 and --flash-attn=on each exit with\n            # \"error: invalid argument\". Accepting the GNU spelling here meant the\n            # switch tore down the resident model and the child then refused to\n            # start, so it is refused while it is still a 400 with somewhere to go.\n            # Splitting it here would be a guess: for a switch the value is not one,\n            # and this module cannot know an ordinary flag's arity.\n            value = token.partition(\"=\")[2]\n            raise ValueError(\n                f\"llama-server does not read an attached value: write '{flag}' and \"\n                f\"'{value[:32]}' as two separate arguments, not '{token[:64]}'\"\n            )\n        else:\n            # Its own value when attached, otherwise the tokens that follow.\n            attached = _value_is_attached(token, flag)\n            if pending_two_value > 0:\n                raise ValueError(f\"llama-server flag '{two_value_flag}' takes two values\")\n            # An attached value is ONE of the two, not the whole option:\n            # \"--control-vector-layer-range=1\" still owes its END, and\n            # llama-server exits on the incomplete option.\n            if flag in _TWO_VALUE_FLAGS:\n                pending_values = 1 if attached else 2\n                pending_two_value = pending_values\n            elif flag in _OPTIONAL_SECOND_VALUE_FLAGS:\n                # Allowed, not owed: pending_two_value stays 0, so nothing here\n                # insists on the second token.\n                pending_values = 1 if attached else 2\n                pending_two_value = 0\n            else:\n                pending_values = 0 if attached else 1\n                pending_two_value = 0\n            two_value_flag = flag\n        out.append(token)\n    if pending_two_value > 0:\n        # Only this shape is checkable: an ordinary flag's arity is unknown here, so","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/llama_server_args.py#L305-L341","documentation":"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.","triggerScenarios":"'--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.","commonSituations":"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.","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."],"exampleFix":"# before\nextra_args = [\"--control-vector-layer-range\", \"10\", \"--top-k\", \"40\"]\n\n# after\nextra_args = [\"--control-vector-layer-range\", \"10\", \"40\", \"--top-k\", \"40\"]","handlingStrategy":"validation","validationCode":"TWO_VALUE = {\"--control-vector-layer-range\"}  # mirror _TWO_VALUE_FLAGS\ndef complete_two_value_flags(tokens):\n    i = 0\n    while i < len(tokens):\n        f = tokens[i]\n        if f in TWO_VALUE and (i + 2 >= len(tokens) or tokens[i+2].startswith('-')):\n            return False\n        i += 1\n    return True","typeGuard":"def two_value_flags_complete(tokens) -> bool:\n    return complete_two_value_flags(tokens)","tryCatchPattern":"try:\n    validate_extra_args(args)\nexcept ValueError as e:\n    if \"takes two values\" in str(e):\n        raise HTTPException(400, \"supply START and END for the named flag\")\n    raise","preventionTips":["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."],"tags":["llama-server","validation","two-value-flag","argv","flag-parsing"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}