{"record":{"id":"8f9b13b768c8e546","repo":"unslothai/unsloth","slug":"extra-llama-server-args-cannot-contain-a-bare-valu","errorCode":null,"errorMessage":"extra llama-server args cannot contain a bare value ('{token[:64]}'); every value must follow its flag","messagePattern":"extra llama-server args cannot contain a bare value \\('(.+?)'\\); every value must follow its flag","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/llama_server_args.py","lineNumber":285,"sourceCode":"            raise ValueError(f\"extra llama-server args are too large (limit {limit} bytes)\")\n        # execve rejects a NUL outright; the rest would reach the child's parser as\n        # invisible characters and be blamed on the flag they are attached to.\n        if _has_control_characters(token):\n            raise ValueError(\"extra llama-server args cannot contain control characters\")\n        flag = _flag_name(token)\n        if flag is not None and flag in _DENYLIST:\n            raise ValueError(\n                f\"llama-server flag '{flag}' is managed by Unsloth Studio \"\n                f\"and cannot be passed as an extra arg\"\n            )\n        if flag is None:\n            # A token belonging to no flag. Today's llama-server answers \"invalid\n            # argument\" and refuses to start, which is a failed load rather than a\n            # 400, and a build that did accept a positional would read it as the\n            # model path: that is the one thing the -m / --model denial exists to\n            # prevent, and it would sidestep the native-path lease as well.\n            if pending_values <= 0:\n                raise ValueError(\n                    \"extra llama-server args cannot contain a bare value \"\n                    f\"('{token[:64]}'); every value must follow its flag\"\n                )\n            pending_values -= 1\n            if pending_two_value > 0:\n                pending_two_value -= 1\n        elif token != token.strip():\n            # _flag_name strips before it looks anything up, so a quoted \"--top-k \"\n            # passed the denylist and the arity walk as --top-k and then went to the\n            # child with the space still on it. llama.cpp looks the whole token up,\n            # so it answers \"error: invalid argument: --top-k\" (measured on b10342),\n            # naming a flag that looks correct in the log. Only flag-shaped tokens:\n            # a VALUE may legitimately end in whitespace, a chat template or a\n            # grammar being the obvious ones.\n            raise ValueError(\n                f\"llama-server does not accept the spaces around '{token[:64]}': \"\n                f\"write it as '{flag}'\"\n            )","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/llama_server_args.py#L267-L303","documentation":"ValueError from llama_server_args.py:285 — a token that is not flag-shaped (bare value) appears while pending_values <= 0, i.e. no preceding flag is expecting a value. Today's llama-server rejects positional arguments with 'invalid argument' (a failed load, not a 400), and a build that did accept positionals would read one as the model path — exactly what the -m/--model denial exists to prevent. So the module insists every value follow its flag.","triggerScenarios":"A value token with no owning flag: the first token in the list is a value; two values follow a one-value flag ('--top-k 40 60'); a flag and its value got separated by a denied flag removal or bad splitting of a quoted shell line.","commonSituations":"Splitting a quoted shell command with shlex incorrectly (quotes consumed, pairing lost); deleting a flag from a stored config but leaving its value; pasting '40 --top-k' with the value first; a UI saving values and flags in separate fields and interleaving them wrongly.","solutions":["Fix the pairing: every value must directly follow the flag that owns it — verify with a walk that flags and values alternate correctly.","Rebuild the list from a canonical structure ({'--top-k': '40'} dict → flag,value pairs) instead of string surgery.","If the first token is bare, a flag is missing — check that flag names start with - and were not eaten by quote handling.","Use shlex.split on the original quoted string so flag/value pairing survives."],"exampleFix":"# before\nextra_args = [\"40\", \"--top-k\", \"--flash-attn\", \"on\"]  # '40' is bare\n\n# after\nextra_args = [\"--top-k\", \"40\", \"--flash-attn\", \"on\"]","handlingStrategy":"validation","validationCode":"def flags_and_values_pair_up(tokens):\n    owed = 0\n    for t in tokens:\n        if _flag_name(t) is not None:\n            owed = 1  # approximation: ordinary flags take one value\n        elif owed > 0:\n            owed -= 1\n        else:\n            return False\n    return True","typeGuard":"def no_bare_leading_value(tokens) -> bool:\n    return _flag_name(tokens[0]) is not None if tokens else True","tryCatchPattern":"try:\n    validate_extra_args(args)\nexcept ValueError as e:\n    if \"bare value\" in str(e):\n        raise HTTPException(400, \"every value must follow its flag\")\n    raise","preventionTips":["Build args from a flag→value mapping, never by string surgery.","Use shlex.split on the original quoted command to preserve pairing.","When deleting a flag from a stored list, delete its value token too.","Ensure the first token of the list is always flag-shaped."],"tags":["llama-server","validation","argv","flag-parsing"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}