{"record":{"id":"a20e1f5045f2a060","repo":"xai-org/x-algorithm","slug":"expected-bool-true-true-false-false-got-val","errorCode":null,"errorMessage":"Expected bool [True, true, False, false], got {val!r}","messagePattern":"Expected bool \\[True, true, False, false\\], got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/python/common/xai-configlib/src/xai_configlib/__init__.py","lineNumber":407,"sourceCode":"                new_dcls = dataclasses.replace(new_dcls, **{name: new_dict})\n\n        if path[-len(key_path) :] == key_path:\n            if value == \"None\" and is_optional(ty_hints[name]):\n                new_dcls = dataclasses.replace(dcls, **{name: None})\n            else:\n                ty = ty_hints[name]\n                new_dcls = dataclasses.replace(new_dcls, **{name: cast_type(ty, value)})\n            used.append(path)\n    return new_dcls\n\n\ndef cast_type(ty: Type[Any], val: str):\n    if ty is bool:\n        if val in (\"False\", \"false\"):\n            return False\n        elif val in (\"True\", \"true\"):\n            return True\n        raise ValueError(f\"Expected bool [True, true, False, false], got {val!r}\")\n    elif is_optional(ty) and val == \"None\":\n        return None\n    elif is_union(ty):\n        subtys = [subty for subty in get_args(ty) if subty is not type(None)]\n        for subty in subtys:\n            try:\n                return cast_type(subty, val)\n            except ValueError:\n                if subty is subtys[-1]:\n                    raise\n        raise TypeError(f\"Got {val} for union type {ty}\")\n    elif is_tuple(ty):\n        if not val:\n            return ()\n        vals = val.split(\",\")\n        tys = get_args(ty)\n        if len(vals) != len(tys):\n            raise TypeError(f\"Tuple {ty} has different number of arguments from given value {vals}\")","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/python/common/xai-configlib/src/xai_configlib/__init__.py#L389-L425","documentation":"cast_type converts string values (usually from CLI overrides) into typed config fields. When the target type is bool, only the strings 'True','true','False','false' are accepted; anything else raises this ValueError.","triggerScenarios":"Passing a bool override like 'use_amp=1', 'use_amp=yes', or 'use_amp=None' where the config field is annotated bool; cast_type(ty=bool, val='1').","commonSituations":"Using 0/1 or y/n conventions from shell scripts, passing empty strings, or overriding a bool field with a value meant for a different field.","solutions":["Use 'True'/'False' (case-insensitive first letter) e.g. 'use_amp=False'","For numeric truthiness, change the config field to int or convert before passing","Quote the value in shell so it arrives intact"],"exampleFix":"# before\nreplace_cli_subs(cfg, [\"use_amp=1\"])\n# after\nreplace_cli_subs(cfg, [\"use_amp=True\"])","handlingStrategy":"type-guard","validationCode":"BOOL_STRINGS = {\"True\", \"true\", \"False\", \"false\"}\ndef is_bool_castable(s: str) -> bool:\n    return s in BOOL_STRINGS","typeGuard":"def is_bool_override(field_type, value: str) -> bool:\n    return field_type is not bool or value in (\"True\",\"true\",\"False\",\"false\")","tryCatchPattern":"try:\n    cast_type(bool, val)\nexcept ValueError as e:\n    raise SystemExit(f\"Bad bool override: {val!r}; use True/False\") from e","preventionTips":["Standardize on True/False in override scripts","Reject 0/1 early with a clear message"],"tags":["config","type-coercion","bool","validation"],"backgroundTag":"type-coercion-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}