xai-org/x-algorithm · error · TypeError

Literal {ty} does not allow for {val!r}

Error message

Literal {ty} does not allow for {val!r}

What it means

For Literal-typed fields, cast_type tries to cast the string to each allowed literal type and checks membership in the Literal's options. If the resulting value is not one of the allowed literals, this TypeError is raised.

Source

Thrown at phoenix/python/common/xai-configlib/src/xai_configlib/__init__.py:456

            result[cast_type(kty, k.strip())] = cast_type(vty, v.strip())
        return result
    elif is_path(ty):
        return Path(val)
    elif is_bytes(ty):
        return base64.b64decode(val.encode("utf-8"))
    elif is_datetime(ty):
        return datetime.datetime.fromisoformat(val)
    elif get_origin(ty) is Literal:
        options = get_args(ty)
        subtys = tuple([type(o) for o in options])
        for subty in subtys:
            try:
                cast = cast_type(subty, val)
            except ValueError:
                continue
            if cast in options:
                return cast
        raise TypeError(f"Literal {ty} does not allow for {val!r}")
    elif isinstance(ty, enum.EnumMeta):
        try:
            return ty(val)
        except ValueError:
            return ty[val]
    elif isinstance(ty, TypeAliasType):
        return cast_type(ty.__value__, val)
    elif ty is re.Pattern:
        return re.compile(val)
    else:
        return ty(val)


def is_union(ty) -> bool:
    return get_origin(ty) in (Union, UnionType)


def is_optional(ty) -> bool:

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Use one of the exact values listed in the Literal annotation
  2. Check casing and quoting; shell may strip or alter quotes
  3. If the new value is legitimate, extend the Literal in the config dataclass

Example fix

# before
replace_cli_subs(cfg, ["optimizer=adafactor"])  # Literal["adam", "adamw"]
# after
replace_cli_subs(cfg, ["optimizer=adamw"])
Defensive patterns

Strategy: validation

Validate before calling

import typing

def literal_allows(ty, val: str):
    if typing.get_origin(ty) is not typing.Literal:
        return True
    opts = typing.get_args(ty)
    try:
        return any(t(val) in opts for t in (str, int, float) if t is not str or isinstance(opts[0], str))
    except ValueError:
        return False

Prevention

When it happens

Trigger: Overriding a field annotated Literal["a","b"] with 'c', or a Literal[1,2] with '3'; the value casts fine but is not in the allowed set.

Common situations: Passing an enum-like string that was renamed in a newer config version, or a casing mismatch ('AdamW' vs 'adamw') since membership is exact.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/3fb7e1acda975992. Report an issue: GitHub.