{"record":{"id":"6548a3241fc4f347","repo":"headroomlabs-ai/headroom","slug":"position-must-be-one-of-positions-got-position","errorCode":null,"errorMessage":"position must be one of {POSITIONS}, got {position!r}","messagePattern":"position must be one of (.+?), got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/evals/adversarial_grid.py","lineNumber":193,"sourceCode":"    if not dicts:\n        return None\n    target = dicts[_position_index(len(dicts), position)]\n    target[\"note\"] = payload\n    return json.dumps(data, indent=2)\n\n\ndef _splice_lines(carrier: str, payload: str, position: str) -> str:\n    lines = carrier.splitlines()\n    if not lines:\n        return payload\n    at = _position_index(len(lines), position) + (1 if position == \"head\" else 0)\n    return \"\\n\".join(lines[:at] + [payload] + lines[at:])\n\n\ndef splice_payload(carrier: str, payload: str, position: str) -> str:\n    \"\"\"Embed a payload into a carrier at head/middle/tail.\"\"\"\n    if position not in POSITIONS:\n        raise ValueError(f\"position must be one of {POSITIONS}, got {position!r}\")\n    spliced = _splice_json(carrier, payload, position)\n    if spliced is not None:\n        return spliced\n    return _splice_lines(carrier, payload, position)\n\n\ndef _benign_lines(carrier: str) -> list[str]:\n    lines = [ln.strip() for ln in carrier.splitlines()]\n    lines = [ln for ln in lines if len(ln) >= _BENIGN_LINE_MIN_CHARS]\n    if len(lines) <= _BENIGN_LINE_SAMPLE:\n        return lines\n    step = len(lines) / _BENIGN_LINE_SAMPLE\n    return [lines[int(i * step)] for i in range(_BENIGN_LINE_SAMPLE)]\n\n\ndef _compression_ratio(original: str, compressed: str) -> float:\n    if not original:\n        return 1.0","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/evals/adversarial_grid.py#L175-L211","documentation":"splice_payload() in headroom.evals.adversarial_grid validates its position argument against the POSITIONS constant (head/middle/tail) and raises ValueError with the allowed set and the offending value for anything else. This is pure input validation before any carrier/payload splicing happens (_splice_json and _splice_lines are only reached with a valid position).","triggerScenarios":"Calling splice_payload(carrier, payload, position) with e.g. 'top', 'start', 'end', 'center', 'Head' (case-sensitive), or None — any string not exactly in POSITIONS. Programmatic callers deriving position from config files or CLI flags most often hit it.","commonSituations":"YAML/JSON eval config with a typo'd position field; passing 0/1/2 indices instead of names; case mismatch ('Middle'); new positions added to a fork but POSITIONS not updated.","solutions":["Use one of the exact allowed values: 'head', 'middle', or 'tail' (match case exactly)","Validate user-supplied position against the module's POSITIONS constant before calling splice_payload — import it rather than hardcoding the list","Normalize input early: `position = position.strip().lower()` then check membership"],"exampleFix":"# before\nsplice_payload(carrier, payload, position=\"start\")\n# ValueError: position must be one of ('head','middle','tail'), got 'start'\n\n# after\nfrom headroom.evals.adversarial_grid import POSITIONS\nposition = position.strip().lower()\nassert position in POSITIONS, f\"position must be one of {POSITIONS}\"\nsplice_payload(carrier, payload, position=position)","handlingStrategy":"validation","validationCode":"from headroom.evals.adversarial_grid import POSITIONS\n\nposition = str(position).strip().lower()\nif position not in POSITIONS:\n    raise ValueError(f\"position must be one of {POSITIONS}, got {position!r}\")\nsplice_payload(carrier, payload, position)","typeGuard":"from headroom.evals.adversarial_grid import POSITIONS\n\ndef is_valid_position(value: object) -> bool:\n    return isinstance(value, str) and value in POSITIONS","tryCatchPattern":null,"preventionTips":["Import POSITIONS from the module instead of duplicating the allowed list","Normalize config-supplied positions (strip+lower) at load time and fail fast","Cover position validation with a unit test enumerating reject cases"],"tags":["validation","evals","adversarial","python","input-validation"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}