{"record":{"id":"30e0689e8c80aa03","repo":"affaan-m/ECC","slug":"valid-candidate-ids-recorded-v1-evaluator-and-bo","errorCode":null,"errorMessage":"valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required","messagePattern":"valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/store.rs","lineNumber":5472,"sourceCode":"        candidate_id: &str,\n        baseline_id: &str,\n        evaluator: &str,\n        samples: &[PairedSample],\n        policy: PromotionPolicy,\n        evidence_ref: &str,\n        health_evidence: &HealthEvidenceSnapshot,\n        health_check: F,\n    ) -> Result<HarnessPromotionOutcome>\n    where\n        F: FnOnce(&str) -> Result<bool>,\n    {\n        if candidate_id.len() != 64\n            || baseline_id.len() != 64\n            || evaluator != \"recorded-v1\"\n            || evidence_ref.trim().is_empty()\n            || evidence_ref.len() > 4096\n        {\n            anyhow::bail!(\"valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required\");\n        }\n        health_evidence.verify()?;\n        if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {\n            anyhow::bail!(\"health evidence does not match candidate and evaluator\");\n        }\n        let comparison = policy.compare(samples)?;\n        let tx = self.conn.unchecked_transaction()?;\n        let stored_candidate_id = Self::resolve_harness_candidate_id(&tx, candidate_id)?;\n        let stored_baseline_id = Self::resolve_harness_candidate_id(&tx, baseline_id)?;\n        let active: String = tx\n            .query_row(\n                \"SELECT candidate_id FROM active_harness_config WHERE slot = 'default'\",\n                [],\n                |row| row.get(0),\n            )\n            .context(\"no active baseline configuration\")?;\n        if active != stored_baseline_id {\n            anyhow::bail!(\"baseline is not the active harness configuration\");","sourceCodeStart":5454,"sourceCodeEnd":5490,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/store.rs#L5454-L5490","documentation":"promote_harness enforces an aggregate input contract: both candidate_id and baseline_id must be 64 chars, evaluator must be exactly \"recorded-v1\" (the only supported evaluator), and evidence_ref must be non-empty and <= 4096 chars. Any failure bails with this message.","triggerScenarios":"Calling promote_harness with candidate_id.len() != 64 or baseline_id.len() != 64, evaluator != \"recorded-v1\", evidence_ref empty, or evidence_ref.len() > 4096.","commonSituations":"Typo in the evaluator string (e.g. \"recorded_v1\", \"recorded-v2\"); passing legacy non-64-char ids; oversized evidence payload; swapping candidate and baseline arguments.","solutions":["Pre-validate both ids are 64 hex chars before calling.","Use a shared EVALUATOR constant (\"recorded-v1\") for both building samples and calling promote, so the strings cannot drift.","Bound evidence_ref to 1..=4096 chars, trimming first."],"exampleFix":"// before\nstore.promote_harness(&candidate_id, &baseline_id, &evaluator, &evidence_ref, ...)?;\n\n// after\nconst EVALUATOR: &str = \"recorded-v1\";\nassert_eq!(candidate_id.len(), 64);\nassert_eq!(baseline_id.len(), 64);\nassert_eq!(evaluator, EVALUATOR);\nlet evidence_ref = evidence_ref.trim();\nassert!(!evidence_ref.is_empty() && evidence_ref.len() <= 4096);\nstore.promote_harness(&candidate_id, &baseline_id, EVALUATOR, evidence_ref, ...)?;","handlingStrategy":"validation","validationCode":"const EVALUATOR: &str = \"recorded-v1\";\n\nfn valid_promotion_args(candidate_id: &str, baseline_id: &str, evaluator: &str, evidence_ref: &str) -> bool {\n    let e = evidence_ref.trim();\n    candidate_id.len() == 64\n        && baseline_id.len() == 64\n        && evaluator == EVALUATOR\n        && !e.is_empty()\n        && e.len() <= 4096\n}\n\nif !valid_promotion_args(&candidate_id, &baseline_id, evaluator, evidence_ref) {\n    return Err(anyhow::anyhow!(\"invalid promotion arguments\"));\n}","typeGuard":"fn promotion_inputs_ok(candidate_id: &str, baseline_id: &str, evaluator: &str, evidence_ref: &str) -> bool {\n    valid_promotion_args(candidate_id, baseline_id, evaluator, evidence_ref)\n}","tryCatchPattern":"match store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, ...) {\n    Ok(out) => { /* handled */ }\n    Err(e) if e.to_string().contains(\"valid candidate ids, recorded-v1 evaluator\") => {\n        // correct evaluator string / id lengths / evidence size and retry\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use a single EVALUATOR constant everywhere instead of string literals.","Wrap promotion calls in a typed helper that takes strongly-typed ids, not raw strings.","Bounds-check evidence_ref at the API boundary, not just inside the store."],"tags":["rust","harness","validation","bounds"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}