BoundaryML/baml · critical

PyTuple::new

Error message

PyTuple::new

What it means

pythonize_strict builds a 2-element tuple (value type, Literal of check names) via PyTuple::new and unwraps with expect("PyTuple::new"). PyTuple::new only fails on unconvertible/to-Convert errors, so this panic indicates a Python object conversion failure inside the Checked-type construction.

Solutions

  1. Upgrade the baml package and its PyO3 runtime to matching versions
  2. Recreate/repair the Python environment (venv) where baml runs
  3. Minimize the schema/checks to isolate which element fails conversion and report a bug
  4. Retry with checks removed from the BAML schema as a workaround
Defensive patterns

Strategy: fallback

Validate before calling

def checks_parsable(checks: list) -> bool:
    return all(isinstance(c, str) for c in checks) and len(checks) > 0

Try / catch

try:
    result = parse_response(...)
except BaseException as e:
    log.warning("checked-type construction failed; retrying without checks")
    result = parse_response_without_checks(...)

Prevention

When it happens

Trigger: One of the tuple elements (value_type or literal_check_names) cannot be converted into a PyO3 tuple element — typically only possible if earlier objects are corrupted or conversion traits fail.

Common situations: Deep internal failure; usually a symptom of environment issues (broken Python runtime) or a PyO3/version incompatibility rather than user error.

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/681a5175f8c478d5. Report an issue: GitHub.

Appendix: source

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

        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)?;
        }

        // Validate the model with the constructed type
        let checked_instance = class_checked_type
            .call_method(model_validate_method, (properties_dict.clone(),), None)
            .expect(model_validate_method);

View on GitHub (pinned to bd85ce9dee)