{"record":{"id":"75f571fc880e8513","repo":"affaan-m/ECC","slug":"score-must-be-finite-and-between-0-and-1","errorCode":null,"errorMessage":"score must be finite and between 0 and 1","messagePattern":"score must be finite and between 0 and 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/harness_eval.rs","lineNumber":436,"sourceCode":"    #[cfg(test)]\n    pub fn calls(&self) -> &[(String, u64)] {\n        &self.calls\n    }\n}\n\nimpl Evaluator for RecordedEvaluator {\n    fn name(&self) -> &str {\n        &self.name\n    }\n\n    fn evaluate(&mut self, candidate_id: &str, seed: u64) -> Result<f64> {\n        self.calls.push((candidate_id.to_string(), seed));\n        let score = *self\n            .scores\n            .get(&(candidate_id.to_string(), seed))\n            .with_context(|| format!(\"missing recorded score for {candidate_id} seed {seed}\"))?;\n        if !score.is_finite() || !(0.0..=1.0).contains(&score) {\n            bail!(\"score must be finite and between 0 and 1\");\n        }\n        Ok(score)\n    }\n\n    fn health_check(&mut self, candidate_id: &str) -> Result<bool> {\n        if self\n            .health_candidate\n            .as_deref()\n            .is_some_and(|expected| expected != candidate_id)\n        {\n            bail!(\"health evidence does not match promoted candidate\");\n        }\n        Ok(self.health_ok)\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct PairedSample {","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/harness_eval.rs#L418-L454","documentation":"During evaluate, the recorded evaluator looks up the pre-recorded score for a (candidate_id, seed) pair and validates it. This error is thrown when the recorded score value is NaN, infinite, or outside the 0.0..=1.0 inclusive range. Scores must be normalized probabilities in [0, 1].","triggerScenarios":"Calling evaluate (or evaluate_paired) with a seed/candidate pair whose pre-recorded score is NaN, f64::INFINITY, negative, or greater than 1.0 in the scores map built via the recorder.","commonSituations":"Recording raw unnormalized metrics (e.g. accuracy * 100, raw loss values, negative rewards); dividing by zero or accumulating float drift during recording producing NaN; recording scores from a metric whose valid range exceeds [0,1].","solutions":["Clamp or normalize recorded scores to the range [0.0, 1.0] before inserting them into the recorder.","Check the recording metric: if it is a percentage, divide by 100; if raw, rescale to [0,1].","Guard against NaN at record time (skip or fix samples producing NaN, e.g. division by zero).","Validate every recorded score (score.is_finite() && (0.0..=1.0).contains(&score)) before running evaluation."],"exampleFix":"// before\nrecorder.record(candidate_id, seed, accuracy * 100.0)?; // 87.5 -> bails at evaluate\n\n// after\nlet score = (accuracy * 100.0 / 100.0).clamp(0.0, 1.0);\nassert!(score.is_finite());\nrecorder.record(candidate_id, seed, score)?;","handlingStrategy":"validation","validationCode":"fn valid_score(s: f64) -> bool { s.is_finite() && (0.0..=1.0).contains(&s) }\n// check every score before evaluate:\ndebug_assert!(recorder_scores().values().copied().all(valid_score));","typeGuard":"fn is_normalized_score(s: f64) -> bool { s.is_finite() && (0.0..=1.0).contains(&s) }","tryCatchPattern":"// map_err with normalization retry\nmatch eval.evaluate(candidate_id, seed) {\n    Err(e) if e.to_string().contains(\"score must be finite\") => {\n        // fix recording pipeline, clamp scores, rebuild evidence, retry once\n    }\n    other => other?,\n}","preventionTips":["Normalize metrics to [0,1] at record time (clamp + rescale).","Guard recording math against division by zero and NaN accumulation.","Add a record-time assertion that every inserted score is finite and in range."],"tags":["validation","score-range","floating-point"],"backgroundTag":"value-out-of-range","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}