BoundaryML/baml · critical

get_item

Error message

get_item

What it means

pythonize_strict builds typing.Literal[...] of check names via literal.get_item(literal_args) and unwraps with expect("get_item"). Panic means dynamically subscripting typing.Literal with the check-name tuple failed (e.g. empty/invalid arguments from the checks vector).

Solutions

  1. Update the baml Python package and engine to matching versions
  2. Simplify check names (avoid exotic characters) in the BAML schema
  3. Verify typing module is importable and intact in the deployed environment
  4. Report as a bug with a minimal repro schema
Defensive patterns

Strategy: type-guard

Validate before calling

from typing import Literal
lit = Literal["check1", "check2"]  # sanity-check dynamic subscript works in your Python

Type guard

def literal_subscript_ok(names: list[str]) -> bool:
    from typing import Literal, get_args
    try:
        return bool(get_args(Literal[tuple(names)]))
    except TypeError:
        return False

Prevention

When it happens

Trigger: A response carrying checks whose names cannot form a valid Literal subscript — e.g. PyTuple::new succeeded but get_item on typing.Literal raised TypeError.

Common situations: Edge cases with unusual check names in the BAML schema; Python runtime version incompatibilities with dynamic Literal subscripting; mismatched engine/client versions.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/1b167f8f46269292. Report an issue: GitHub.

Appendix: source

Thrown at engine/language_client_python/src/types/function_results.rs:323

    // Import the necessary modules and objects
    let typing = py.import("typing").expect("typing");
    let literal = typing.getattr("Literal").expect("Literal");

    let value_with_possible_checks = if !checks.is_empty() {
        // Generate the Python checks
        let python_checks = pythonize_checks(py, cls_module, &checks, model_validate_method)
            .expect("pythonize_checks");

        // Get the type of the original value
        let value_type = py_value_without_constraints.bind(py).get_type();

        // Collect check names as &str and turn them into a Python tuple
        let check_names: Vec<&str> = checks.iter().map(|check| check.name.as_str()).collect();
        let literal_args = PyTuple::new(py, check_names)?;

        // Call Literal[...] dynamically
        let literal_check_names = literal.get_item(literal_args).expect("get_item");

        let class_checked_type_constructor =
            cls_module.getattr("Checked").expect("getattr(Checked)");

        // Prepare type parameters for Checked[...]
        let type_parameters_tuple =
            PyTuple::new(py, [value_type.as_ref(), &literal_check_names]).expect("PyTuple::new");

        // Create the Checked type using __class_getitem__
        let class_checked_type: Bound<'_, PyAny> = class_checked_type_constructor
            .call_method1("__class_getitem__", (type_parameters_tuple,))
            .expect("__class_getitem__");

        // Prepare the properties dictionary
        let properties_dict = pyo3::types::PyDict::new(py);
        properties_dict.set_item("value", py_value_without_constraints)?;
        if !checks.is_empty() {
            properties_dict.set_item("checks", python_checks)?;

View on GitHub (pinned to bd85ce9dee)