keras-team/keras · error · ValueError
Unrecognized value for `merge_mode`. Received
Error message
Unrecognized value for `merge_mode`. Received: {self.merge_mode}. Expected one of {"concat", "sum", "ave", "mul"}. What it means
Raised in the fused-backend path of Bidirectional (e.g. JAX/TF fused RNN helper) when self.merge_mode is not one of 'concat', 'sum', 'ave', 'mul'. Like the non-fused branch, this is a sentinel guard: valid construction makes it unreachable, so it signals merge_mode was set to an unsupported value after init (note the fused path does not support None).
Solutions
- Use one of 'concat', 'sum', 'ave', or 'mul'; in the fused path None is not handled, so switch to 'concat' or another mode
- Restore merge_mode to its constructor-validated value if it was changed or corrupted during (de)serialization
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at keras/src/layers/rnn/bidirectional.py:366 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/6c862140fab040b9.
Report an issue: GitHub.
Appendix: source
Thrown at keras/src/layers/rnn/bidirectional.py:366
y = ops.cast(y, self.compute_dtype)
y_rev = ops.cast(y_rev, self.compute_dtype)
# The fused backend helper already returns backward outputs in
# original time order, so the per-layer `ops.flip(y_rev)` that the
# non-fused path applies is unnecessary here.
if self.merge_mode == "concat":
output = ops.concatenate([y, y_rev], axis=-1)
elif self.merge_mode == "sum":
output = y + y_rev
elif self.merge_mode == "ave":
output = (y + y_rev) / 2
elif self.merge_mode == "mul":
output = y * y_rev
elif self.merge_mode is None:
output = (y, y_rev)
else:
raise ValueError(
"Unrecognized value for `merge_mode`. "
f"Received: {self.merge_mode}. "
'Expected one of {"concat", "sum", "ave", "mul"}.'
)
if self.return_state:
states = tuple(fwd_states + bwd_states)
if self.merge_mode is None:
return output + states
return (output,) + states
return output
def _can_attempt_fused_gru(self, mask, initial_state=None):
# Layer-level preconditions for dispatching to
# `backend.bidirectional_gru`. The structure matches the LSTM gate
# above. The only differences are the layer type, the
# `reset_after=True` requirement (the cuDNN GRU formulation), and
# the state count (one h per direction, so length 2).View on GitHub (pinned to 7a34a03db6)