keras-team/keras · error · ValueError
In a nested call() argument, you cannot mix tensors and non-
Error message
In a nested call() argument, you cannot mix tensors and non-tensors. Received invalid mixed argument: {name}={value} What it means
When Keras inspects a nested (list/tuple/dict-valued) keyword argument to call(), it flattens the values and requires them to be either all tensors (backend or symbolic) or all non-tensors. This ValueError fires when a single nested argument mixes tensors and plain Python values, because Keras cannot decide whether the argument is graph input data or plain configuration.
Source
Thrown at keras/src/layers/layer.py:1938
for name, value in bound_args.arguments.items():
arg_dict[name] = value
arg_names.append(name)
if is_backend_tensor_or_symbolic(value):
tensor_args.append(value)
tensor_arg_names.append(name)
tensor_arg_dict[name] = value
elif tree.is_nested(value) and len(value) > 0:
flat_values = tree.flatten(value)
if all(
is_backend_tensor_or_symbolic(x, allow_none=True)
for x in flat_values
):
tensor_args.append(value)
tensor_arg_names.append(name)
tensor_arg_dict[name] = value
nested_tensor_arg_names.append(name)
elif any(is_backend_tensor_or_symbolic(x) for x in flat_values):
raise ValueError(
"In a nested call() argument, "
"you cannot mix tensors and non-tensors. "
"Received invalid mixed argument: "
f"{name}={value}"
)
self.arguments_dict = arg_dict
self.argument_names = arg_names
self.tensor_arguments_dict = tensor_arg_dict
self.tensor_arguments_names = tensor_arg_names
self.nested_tensor_argument_names = nested_tensor_arg_names
self.first_arg = arg_dict[arg_names[0]]
if all(
backend.is_tensor(x) for x in self.tensor_arguments_dict.values()
):
self.eager = True
else:
self.eager = False
View on GitHub (pinned to 7a34a03db6)
Solutions
- Split the argument into two: one pure-tensor argument (e.g. boxes) and one plain-Python argument (e.g. box_config)
- Convert the non-tensor entries into constants of the same backend (e.g. keras.ops.cast / backend constants) so the whole nested value is tensors
- Move static configuration into the layer constructor instead of call()
Example fix
# before
out = layer(x, anchors={'sizes': sizes_tensor, 'ratios': [1.0, 2.0]}) # ValueError
# after
layer = AnchorLayer(ratios=[1.0, 2.0])
out = layer(x, anchors=sizes_tensor) Defensive patterns
Strategy: validation
Validate before calling
flat = keras.tree.flatten(nested_arg) is_tensor = lambda v: hasattr(v, 'shape') and hasattr(v, 'dtype') flags = [is_tensor(v) for v in flat] assert all(flags) or not any(flags), 'mixed tensors and non-tensors in nested arg'
Try / catch
try:
out = layer(x, nested=arg)
except ValueError as e:
if 'cannot mix tensors and non-tensors' in str(e):
out = layer(x, tensors=tensor_part, config=py_part) Prevention
- Keep each nested call() argument homogeneous: all tensors or all plain Python values
- Pass static configuration via the constructor
- Split mixed structures into separate keyword arguments
When it happens
Trigger: Calling a layer with a nested argument like layer(x, boxes=[tensor_a, (10, 20)]) or layer(x, anchors={'sizes': some_tensor, 'ratios': [1.0, 2.0]}) where the flattened structure contains both backend/KerasTensors and scalars/tuples.
Common situations: Detection layers that take a list of anchor boxes plus learned tensors; passing normalized coordinates alongside tensors; refactoring a flat tensor argument into a mixed config dict.
Related errors
- Unknown activation function '{activation}' cannot be seriali
- Could not interpret activation function identifier: {identif
- ConvNeXt does not support the `channels_first` image data fo
- If using `weights="imagenet"` with `include_top=True`, `clas
- The `weights` argument should be either `None` (random initi
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/a3edc0f34f350288.
Report an issue: GitHub.