{"record":{"id":"4531c0a9060d7a38","repo":"keras-team/keras","slug":"threshold-values-must-be-in-0-1-received-inv","errorCode":null,"errorMessage":"Threshold values must be in [0, 1]. Received: {invalid_thresholds}","messagePattern":"Threshold values must be in \\[0, 1\\]\\. Received: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/metrics/metrics_utils.py","lineNumber":20,"sourceCode":"from enum import Enum\n\nimport numpy as np\n\nfrom keras.src import backend\nfrom keras.src import ops\nfrom keras.src.losses.loss import squeeze_or_expand_to_same_rank\nfrom keras.src.utils.python_utils import to_list\n\nNEG_INF = -1e10\n\n\ndef assert_thresholds_range(thresholds):\n    if thresholds is not None:\n        invalid_thresholds = [\n            t for t in thresholds if t is None or t < 0 or t > 1\n        ]\n        if invalid_thresholds:\n            raise ValueError(\n                \"Threshold values must be in [0, 1]. \"\n                f\"Received: {invalid_thresholds}\"\n            )\n\n\ndef parse_init_thresholds(thresholds, default_threshold=0.5):\n    if thresholds is not None:\n        assert_thresholds_range(to_list(thresholds))\n    thresholds = to_list(\n        default_threshold if thresholds is None else thresholds\n    )\n    return thresholds\n\n\nclass ConfusionMatrix(Enum):\n    TRUE_POSITIVES = \"tp\"\n    FALSE_POSITIVES = \"fp\"\n    TRUE_NEGATIVES = \"tn\"","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/metrics/metrics_utils.py#L2-L38","documentation":"Keras validates that every threshold used by thresholded metrics (Precision, Recall, AUC with explicit thresholds) lies in [0,1]. parse_init_thresholds() calls assert_thresholds_range(), which collects offending values and raises this ValueError. Thresholds below 0, above 1, or None entries inside the list trigger it.","triggerScenarios":"Constructing keras.metrics.Precision(thresholds=[0.2, 1.5]), Recall(thresholds=[-0.1]), or AUC(thresholds=[None, 0.5]) - any value <0, >1, or None inside the thresholds list.","commonSituations":"Reading thresholds from a config file or hyperparameter sweep where values escape [0,1]; mixing logit-scale values (e.g. 5.0) into probability thresholds.","solutions":["Clamp or filter thresholds to [0,1]: [t for t in thresholds if 0 <= t <= 1].","If you have logit-scale scores, convert to probabilities with a sigmoid before using them as thresholds.","Remove None entries from the thresholds list; pass thresholds=None to use the default 0.5."],"exampleFix":"# before\nmetric = keras.metrics.Precision(thresholds=[0.5, 1.2])\n\n# after\nmetric = keras.metrics.Precision(thresholds=[0.5, 0.9])","handlingStrategy":"validation","validationCode":"def check_thresholds(thresholds):\n    if thresholds is not None:\n        bad = [t for t in thresholds if t is None or t < 0 or t > 1]\n        if bad:\n            raise ValueError(f'thresholds outside [0,1]: {bad}')\n    return thresholds","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate config-sourced thresholds against [0,1] before constructing metrics.","Convert logit-scale values with a sigmoid before using them as thresholds."],"tags":["keras","metrics","thresholds","validation","valueerror"],"backgroundTag":"argument-out-of-range","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}