cube-js/cube · error · minijinja::Error
Unable to convert Map to Python object: key must be string,
Error message
Unable to convert Map to Python object: key must be string, actual: {} What it means
When converting a MiniJinja `Map` to a Python object, every key must be a string. `from_minijinja_value` reads each key and, if `key.as_str()` is `None`, raises this error including the actual key kind. Python object (dict) keys are expected to be strings in this bridge.
Source
Thrown at packages/cubejs-backend-native/src/template/mj_value/python.rs:83
}
mjv::ValueKind::Map => {
let mut obj = CLReprObject::new(if from.is_kwargs() {
CLReprObjectKind::KWargs
} else {
CLReprObjectKind::Object
});
for key in from.try_iter()? {
let value = if let Ok(v) = from.get_item(&key) {
from_minijinja_value(&v)?
} else {
CLRepr::Null
};
let key_str = if let Some(key) = key.as_str() {
key.to_string()
} else {
return Err(mj::Error::new(
mj::ErrorKind::InvalidOperation,
format!(
"Unable to convert Map to Python object: key must be string, actual: {}",
key.kind()
),
));
};
obj.insert(key_str, value);
}
Ok(CLRepr::Object(obj))
}
other => Err(mj::Error::new(
mj::ErrorKind::InvalidOperation,
format!("Converting from {:?} to Python is not supported", other),
)),
}View on GitHub (pinned to 7d981676b3)
Solutions
- Convert keys to strings in the template: use `|string` on keys when constructing the map.
- Key the map by string loop variables (`loop.index | string`) instead of raw integers.
- Restructure the data as a sequence of objects if keys are inherently numeric.
- Handle the conversion in Python from a JSON string instead of a map value.
Example fix
// before
{% set m = {loop.index: item} %}
// after
{% set m = {loop.index.__string__(): item} %} {# or build with string keys #} Defensive patterns
Strategy: validation
Validate before calling
// in Jinja, ensure map keys are strings:
{% set m = {} %}{% for k, v in data %}{% set _ = m.update({k | string: v}) %}{% endfor %} Type guard
fn map_keys_all_strings(v: &serde_json::Map<String, serde_json::Value>) -> bool { true } // enforce at map construction Prevention
- Never build maps with numeric keys for Python interop
- Use |string on keys derived from loop indices
- Represent numeric-keyed data as arrays of objects instead
When it happens
Trigger: A template passes a map with non-string keys (e.g. integer keys like `{1: 'a'}`) into a Python filter, method call, or as a nested value during conversion.
Common situations: Building dicts in Jinja with numeric keys from loops (`{i: value}` inside a for loop), JSON objects produced with numeric keys, or merging maps keyed by indices.
Related errors
- Converting from {:?} to Python is not supported
- Unable to convert Seq to Python
- Error while calling filter: {}
- function registration must be used with functions, actual: '
- unable to register variable: name '%s' is already in use for
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/ba871ba481d218f4.
Report an issue: GitHub.