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
- Update the baml Python package and engine to matching versions
- Simplify check names (avoid exotic characters) in the BAML schema
- Verify typing module is importable and intact in the deployed environment
- 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
- Pin compatible Python versions in your deployment
- Keep engine/client versions aligned
- Test check parsing after any BAML upgrade
- Keep check names simple identifiers
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
- getattr(Checked)
- pythonize_checks
- PyTuple::new
- ai.Prompt._data must contain baml_builtins2::PromptAst
- ai.Prompt.messages receiver must be an ai.Prompt instance
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)