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

  1. Split the argument into two: one pure-tensor argument (e.g. boxes) and one plain-Python argument (e.g. box_config)
  2. 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
  3. 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

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


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/a3edc0f34f350288. Report an issue: GitHub.