keras-team/keras · error · ValueError

`true_fn` and `false_fn` should return outputs of the same k

Error message

`true_fn` and `false_fn` should return outputs of the same kind (struct, dtype and shape). Got {true_fn_spec} and {false_fn_spec} instead.

What it means

cond requires both branches to be interchangeable: identical pytree structure, dtypes and shapes. Keras compares the computed output specs of true_fn and false_fn and rejects mismatches because backends compile both paths.

Source

Thrown at keras/src/ops/core.py:1106

                        e,
                        self.call,
                        args,
                        kwargs,
                        object_name=(f"{self.__class__.__name__}.call()"),
                    ) from None
                raise

        # Plain flow.
        return call_fn(*args, **kwargs)

    def call(self, pred, true_fn, false_fn):
        return backend.core.cond(pred, true_fn, false_fn)

    def compute_output_spec(self, pred, true_fn, false_fn):
        true_fn_spec = backend.compute_output_spec(true_fn)
        false_fn_spec = backend.compute_output_spec(false_fn)
        if not self._check_output_spec(true_fn_spec, false_fn_spec):
            raise ValueError(
                "`true_fn` and `false_fn` should return outputs "
                "of the same kind (struct, dtype and shape). "
                f"Got {true_fn_spec} and {false_fn_spec} instead."
            )
        return true_fn_spec

    def _check_output_spec(self, true_fn_spec, false_fn_spec):
        try:
            tree.assert_same_structure(true_fn_spec, false_fn_spec)
        except:
            return False

        def check_leaf(t_spec, f_spec):
            if t_spec is None or f_spec is None:
                return t_spec is None and f_spec is None
            return t_spec.shape == f_spec.shape and t_spec.dtype == f_spec.dtype

        same = tree.map_structure(check_leaf, true_fn_spec, false_fn_spec)

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Make both branches return the same structure, dtype, and rank
  2. Cast outputs in one branch to match the other (keras.ops.cast)
  3. Return tuples of the same arity from both branches

Example fix

# before
keras.ops.cond(p, lambda: x, lambda: (x, x))

# after
keras.ops.cond(p, lambda: (x,), lambda: (x,))
Defensive patterns

Strategy: validation

Validate before calling

ts = keras.ops.compute_output_spec(true_fn)
fs = keras.ops.compute_output_spec(false_fn)
assert str(ts) == str(fs), f'{ts} vs {fs}'

Try / catch

try:
    keras.ops.cond(p, tfn, ffn)
except ValueError:
    fix ffn to match tfn output spec

Prevention

When it happens

Trigger: keras.ops.cond(pred, lambda: x, lambda: keras.ops.cast(x, 'float16')) or branches returning (x,) vs (x, y)

Common situations: Data-dependent branching with jitted backends (JAX), quantization-aware branches, or dtype-mixed training/eval paths

Related errors


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