huggingface/transformers · error · TypeError
Cannot flatten {type(obj).__name__} for pytree context
Error message
Cannot flatten {type(obj).__name__} for pytree context What it means
The catch-all branch of _flatten_to_context: an object in the traced program's pytree context is not one of the supported types (None/bool/int/float/str, enum, tuple/list/set/frozenset, dict-like, or any object with __dict__). Types without __dict__ — e.g. classes using __slots__, C-extension types, complex tensors or numpy scalars — cannot be serialized into the export context and raise this TypeError naming the type.
Source
Thrown at src/transformers/exporters/exporter_dynamo.py:518
"v": {k: _flatten_to_context(v, tensors) for k, v in obj.items()},
}
if isinstance(obj, (tuple, list, set, frozenset)): # sequences/sets incl. NamedTuple
return {
"_t": "seq",
"p": _class_to_path(cls),
"v": [_flatten_to_context(i, tensors) for i in obj],
}
if isinstance(obj, types.MethodType):
# A bound method can't be flattened into pytree context. Models shouldn't bind methods onto
# objects they return at forward time (e.g. recurrent_gemma binds `get_seq_length`/
# `get_mask_sizes` onto its `DynamicCache`) — that pattern isn't exportable; such a model is
# skipped until the binding is refactored away (e.g. into a `Cache` subclass).
raise TypeError("Cannot flatten a bound method for pytree context")
if hasattr(obj, "__dict__"):
state = {k: _flatten_to_context(v, tensors) for k, v in vars(obj).items()}
return {"_t": "obj", "p": _class_to_path(cls), "s": state}
raise TypeError(f"Cannot flatten {type(obj).__name__} for pytree context")
def _unflatten_from_context(ctx: Any, tensors: list) -> Any:
"""Reconstruct an object from its JSON-native context, substituting tensor index markers."""
# --- Pure Python / JSON-native ---
if ctx is None or type(ctx) in (bool, int, float, str):
return ctx
if type(ctx) is list:
return [_unflatten_from_context(i, tensors) for i in ctx]
if type(ctx) is dict and "_t" not in ctx:
return {k: _unflatten_from_context(v, tensors) for k, v in ctx.items()}
# --- Torch objects ---
t = ctx["_t"]
if t == "tensor":
return tensors[ctx["i"]]
if t == "layout":
return getattr(torch, ctx["n"])View on GitHub (pinned to a597f97485)
Solutions
- Convert the offending value to a supported type before export (int/float/str, tuple/list/dict, or a plain class with __dict__).
- If it is your class using __slots__, drop __slots__ or add a __dict__-carrying base so state can be captured.
- Keep numpy scalars out of module/config state — cast to Python builtins at model init.
- Locate the value first: the error names the type; grep your model for that type in attributes reachable from forward.
Example fix
# before (model code)
class WindowSpec:
__slots__ = ("size", "stride") # no __dict__ -> unflattenable
# after
class WindowSpec: # plain class with __dict__
def __init__(self, size, stride):
self.size, self.stride = size, stride Defensive patterns
Strategy: type-guard
Validate before calling
import types
SUPPORTED_PRIMITIVES = (type(None), bool, int, float, str)
def flattenable(obj) -> bool:
if obj is None or isinstance(obj, SUPPORTED_PRIMITIVES):
return True
if isinstance(obj, (tuple, list, set, frozenset)):
return all(flattenable(i) for i in obj)
if isinstance(obj, types.MappingProxyType | dict):
return all(flattenable(v) for v in obj.values())
if hasattr(obj, "__dict__"):
return all(flattenable(v) for v in vars(obj).values())
return False
assert flattenable(model_state_reachable_from_forward), "non-serializable object would break export" Type guard
def is_pytree_context_safe(obj) -> bool:
return flattenable(obj) Try / catch
try:
DynamoExporter().export(model, inputs, cfg)
except TypeError as e:
if "Cannot flatten" in str(e):
# str(e) names the type — find and convert it in model state, then retry once
bad = str(e).split("Cannot flatten")[1].split(" for pytree")[0].strip()
raise RuntimeError(f"convert {bad} instances in model state to plain builtins/dataclasses") from e
raise Prevention
- Keep model/config state to builtins and plain classes (no __slots__, no numpy scalars, no C objects)
- Cast numpy values to int/float/str at model init
- Smoke-test custom models with a tiny Dynamo export before adding them to the export matrix
When it happens
Trigger: A model config/attribute reachable from the traced graph holds a slotted class, a numpy scalar, a complex number, or an extension object; the flattener walks it while building the JSON-native context for the ExportedProgram.
Common situations: Custom model code storing non-standard objects (slots-based dataclasses, numpy types, third-party C objects) in state that dynamo must capture; upgrading numpy/torch so a previously-tolerated type now takes the unsupported path.
Related errors
- Cannot flatten a bound method for pytree context
- Expected config to be a DynamoConfig or dict, got {type(conf
- `num_head` was provided as a list of length {len(num_heads)}
- `head_dim` was provided as a list of length {len(num_heads)}
- Provided path ({save_directory}) should be a directory, not
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/4ce16539dc49d381.
Report an issue: GitHub.