keras-team/keras · error · ValueError

Invalid keys: "{invalid_keys}". Valid variable key options a

Error message

Invalid keys: "{invalid_keys}". Valid variable key options are: "{list(ConfusionMatrix)}"

What it means

The counterpart of the empty-dict check: if variables_to_update contains any key not in the ConfusionMatrix enum, update_confusion_matrix_variables() raises this ValueError listing the invalid keys. Mixed dicts (some valid, some invalid keys) are rejected too - validity is all-or-nothing.

Source

Thrown at keras/src/metrics/metrics_utils.py:455

        # details.
        thresholds_with_epsilon = thresholds[0] < 0.0 or thresholds[-1] > 1.0

    thresholds = ops.convert_to_tensor(thresholds, dtype=variable_dtype)
    num_thresholds = ops.shape(thresholds)[0]

    if multi_label:
        one_thresh = ops.equal(
            np.array(1, dtype="int32"),
            len(thresholds.shape),
        )
    else:
        one_thresh = np.array(True, dtype="bool")

    invalid_keys = [
        key for key in variables_to_update if key not in list(ConfusionMatrix)
    ]
    if invalid_keys:
        raise ValueError(
            f'Invalid keys: "{invalid_keys}". '
            f'Valid variable key options are: "{list(ConfusionMatrix)}"'
        )

    y_pred, y_true = squeeze_or_expand_to_same_rank(y_pred, y_true)
    if sample_weight is not None:
        sample_weight = ops.expand_dims(
            ops.cast(sample_weight, dtype=variable_dtype), axis=-1
        )
        _, sample_weight = squeeze_or_expand_to_same_rank(
            y_true, sample_weight, expand_rank_1=False
        )

    if top_k is not None:
        y_pred = _filter_top_k(y_pred, top_k)

    if class_id is not None:
        if len(y_pred.shape) == 1:

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Keep only ConfusionMatrix enum keys in variables_to_update; maintain extra state in separate metric variables updated outside this call.
  2. Re-check for typos or string/enum mixing after refactoring.

Example fix

# before
vars_ = {ConfusionMatrix.TP: self.tp, 'custom': self.custom_var}
metrics_utils.update_confusion_matrix_variables(vars_, y_true, y_pred)

# after
vars_ = {ConfusionMatrix.TP: self.tp}
metrics_utils.update_confusion_matrix_variables(vars_, y_true, y_pred)
self.custom_var.update(custom_op)  # update extra state separately
Defensive patterns

Strategy: type-guard

Validate before calling

from keras.src.metrics.metrics_utils import ConfusionMatrix
def all_keys_valid(d):
    return all(k in list(ConfusionMatrix) for k in (d or {}))

Type guard

def is_valid_cm_dict(d) -> bool:
    from keras.src.metrics.metrics_utils import ConfusionMatrix
    return all(k in list(ConfusionMatrix) for k in (d or {}))

Prevention

When it happens

Trigger: Calling update_confusion_matrix_variables(variables_to_update={ConfusionMatrix.TP: v, 'recall': r}) - an extraneous key alongside valid ones.

Common situations: Extending a copied metric implementation by putting extra state keys into the same dict instead of separate variables.

Related errors


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