affaan-m/ECC · error

invalid canonical health evidence snapshot

Error message

invalid canonical health evidence snapshot

What it means

RecordedEvidence::verify checks that the evidence snapshot is canonical: candidate_id must be exactly 64 lowercase hex characters (plus other structural checks). This error means the health evidence snapshot has a malformed candidate id or otherwise fails canonical-form validation, so it cannot be trusted as a canonical health record.

Solutions

  1. Use the id returned by HarnessCandidate (e.g. id_for_v2()/id_for_v1()) verbatim; never retype or transform it.
  2. Lowercase the id and re-check it is 64 hex chars before persisting evidence: id.to_lowercase() with a length/charset check.
  3. Regenerate the evidence snapshot from the recorded evaluator flow so the id is derived from the candidate, not supplied manually.
  4. Fix the export/import step that altered the id (e.g. case-folding, truncation, or line-wrapping).

Example fix

// before
let evidence = RecordedEvidence { candidate_id: params.candidate_id.to_uppercase(), .. };

// after
let candidate_id = params.candidate_id.trim().to_lowercase();
assert_eq!(candidate_id.len(), 64);
assert!(candidate_id.bytes().all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase()));
let evidence = RecordedEvidence { candidate_id, .. };
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_canonical_candidate_id(id: &str) -> bool {
    id.len() == 64
        && id.bytes().all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
}

Type guard

fn narrow_candidate_id(raw: &str) -> Option<CandidateId> {
    let s = raw.trim().to_lowercase();
    (s.len() == 64 && s.bytes().all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b)))
        .then(|| CandidateId(s))
}

Try / catch

match evidence.verify() {
    Ok(()) => proceed(),
    Err(e) if e.to_string().contains("invalid canonical health evidence") => bail!("corrupt candidate id in evidence; regenerate snapshot"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Loading or deserializing a RecordedEvidence whose candidate_id is shorter/longer than 64 chars, contains non-hex characters (uppercase A-F, 'g'-'z', punctuation), or is empty; then calling verify (directly or via canonical_json / evaluate_promote_and_health_check).

Common situations: Truncating or reformatting the candidate id (e.g. uppercasing through a shell pipeline); copying an id from logs that wrapped lines; constructing evidence by hand in a test with a placeholder id like "test-candidate"; exporting data through a system that altered the id's case.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/3c20b814080ad804. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/harness_eval.rs:348

    pub fn canonical_json(&self) -> Result<String> {
        self.verify()?;
        Ok(serde_json::to_string(self)?)
    }

    pub fn digest(&self) -> Result<String> {
        Ok(sha256_hex(self.canonical_json()?.as_bytes()))
    }

    pub fn verify(&self) -> Result<()> {
        if self.schema_version != 1
            || self.evaluator != "recorded-v1"
            || self.candidate_id.len() != 64
            || !self
                .candidate_id
                .bytes()
                .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
        {
            bail!("invalid canonical health evidence snapshot");
        }
        Ok(())
    }
}

pub struct RecordedEvaluator {
    name: String,
    scores: BTreeMap<(String, u64), f64>,
    health_ok: bool,
    health_candidate: Option<String>,
    calls: Vec<(String, u64)>,
}

impl RecordedEvaluator {
    #[cfg(test)]
    pub fn new(scores: BTreeMap<(String, u64), f64>, health_ok: bool) -> Self {
        Self {
            name: "recorded-v1".into(),

View on GitHub (pinned to 8321021c54)