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

  1. Use one of 'concat', 'sum', 'ave', or 'mul'; in the fused path None is not handled, so switch to 'concat' or another mode
  2. 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)