keras-team/keras · error · ValueError
All cells must have a `call` method. Received cell without a
Error message
All cells must have a `call` method. Received cell without a `call` method: {cell} What it means
StackedRNNCells wraps a list of RNN cell objects (e.g. SimpleRNNCell instances) that an RNN layer steps through. Each cell must be a duck-typed RNN cell exposing both a `call` method and a `state_size` attribute; `__init__` checks every element with `dir(cell)` and rejects any object missing `call`. This fails at construction, before any computation.
Source
Thrown at keras/src/layers/rnn/stacked_rnn_cells.py:38
batch_size = 3
sentence_length = 5
num_features = 2
new_shape = (batch_size, sentence_length, num_features)
x = np.reshape(np.arange(30), new_shape)
rnn_cells = [keras.layers.LSTMCell(128) for _ in range(2)]
stacked_lstm = keras.layers.StackedRNNCells(rnn_cells)
lstm_layer = keras.layers.RNN(stacked_lstm)
result = lstm_layer(x)
```
"""
def __init__(self, cells, **kwargs):
super().__init__(**kwargs)
for cell in cells:
if "call" not in dir(cell):
raise ValueError(
"All cells must have a `call` method. "
f"Received cell without a `call` method: {cell}"
)
if "state_size" not in dir(cell):
raise ValueError(
"All cells must have a `state_size` attribute. "
f"Received cell without a `state_size`: {cell}"
)
self.cells = cells
@property
def state_size(self):
return [c.state_size for c in self.cells]
@property
def output_size(self):
if getattr(self.cells[-1], "output_size", None) is not None:
return self.cells[-1].output_sizeView on GitHub (pinned to 7a34a03db6)
Solutions
- Pass instantiated cell objects: StackedRNNCells(cells=[SimpleRNNCell(8), GRUCell(8)])
- For custom cells, implement both call(self, inputs, states) returning (output, new_states) and a state_size attribute
- Do not pass Layers or dicts; convert them to proper Keras cells first
Example fix
# before cells = keras.layers.StackedRNNCells([keras.layers.SimpleRNNCell, keras.layers.GRUCell]) # after cells = keras.layers.StackedRNNCells([keras.layers.SimpleRNNCell(8), keras.layers.GRUCell(8)])
Defensive patterns
Strategy: type-guard
Validate before calling
assert all(hasattr(c, 'call') and hasattr(c, 'state_size') for c in cells), 'all entries must be RNN cells' stacked = keras.layers.StackedRNNCells(cells=cells)
Type guard
def is_rnn_cell(obj) -> bool:
return hasattr(obj, 'call') and hasattr(obj, 'state_size') Prevention
- Always pass instantiated cell objects, never classes or dicts
- Keep custom cells aligned with the Keras cell contract: call(inputs, states) returning (output, new_states) plus state_size
When it happens
Trigger: Passing plain objects, dicts, Keras Layer instances that are not cells, or class objects (instead of instantiated cell objects) to keras.layers.StackedRNNCells(cells=[...]). E.g. cells=[SimpleRNNCell] (class, not instance) or cells=[{'units': 8}].
Common situations: Migrating tf.keras code where cell lists were built differently; forgetting parentheses when instantiating cells; passing a Layer subclass that lacks the RNN cell interface; wrapping non-cell custom layers in a stacked RNN.
Related errors
- Received an invalid value for argument `units`, expected a p
- All cells must have a `state_size` attribute. Received cell
- Unknown activation function '{activation}' cannot be seriali
- Could not interpret activation function identifier: {identif
- ConvNeXt does not support the `channels_first` image data fo
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/757a5c16dd32c7ab.
Report an issue: GitHub.