affaan-m/ECC · error · anyhow::Error

valid candidate ids, recorded-v1 evaluator, and bounded evid

Error message

valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required

What it means

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.

Source

Thrown at ecc2/src/session/store.rs:5472

        candidate_id: &str,
        baseline_id: &str,
        evaluator: &str,
        samples: &[PairedSample],
        policy: PromotionPolicy,
        evidence_ref: &str,
        health_evidence: &HealthEvidenceSnapshot,
        health_check: F,
    ) -> Result<HarnessPromotionOutcome>
    where
        F: FnOnce(&str) -> Result<bool>,
    {
        if candidate_id.len() != 64
            || baseline_id.len() != 64
            || evaluator != "recorded-v1"
            || evidence_ref.trim().is_empty()
            || evidence_ref.len() > 4096
        {
            anyhow::bail!("valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required");
        }
        health_evidence.verify()?;
        if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {
            anyhow::bail!("health evidence does not match candidate and evaluator");
        }
        let comparison = policy.compare(samples)?;
        let tx = self.conn.unchecked_transaction()?;
        let stored_candidate_id = Self::resolve_harness_candidate_id(&tx, candidate_id)?;
        let stored_baseline_id = Self::resolve_harness_candidate_id(&tx, baseline_id)?;
        let active: String = tx
            .query_row(
                "SELECT candidate_id FROM active_harness_config WHERE slot = 'default'",
                [],
                |row| row.get(0),
            )
            .context("no active baseline configuration")?;
        if active != stored_baseline_id {
            anyhow::bail!("baseline is not the active harness configuration");

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Pre-validate both ids are 64 hex chars before calling.
  2. Use a shared EVALUATOR constant ("recorded-v1") for both building samples and calling promote, so the strings cannot drift.
  3. Bound evidence_ref to 1..=4096 chars, trimming first.

Example fix

// before
store.promote_harness(&candidate_id, &baseline_id, &evaluator, &evidence_ref, ...)?;

// after
const EVALUATOR: &str = "recorded-v1";
assert_eq!(candidate_id.len(), 64);
assert_eq!(baseline_id.len(), 64);
assert_eq!(evaluator, EVALUATOR);
let evidence_ref = evidence_ref.trim();
assert!(!evidence_ref.is_empty() && evidence_ref.len() <= 4096);
store.promote_harness(&candidate_id, &baseline_id, EVALUATOR, evidence_ref, ...)?;
Defensive patterns

Strategy: validation

Validate before calling

const EVALUATOR: &str = "recorded-v1";

fn valid_promotion_args(candidate_id: &str, baseline_id: &str, evaluator: &str, evidence_ref: &str) -> bool {
    let e = evidence_ref.trim();
    candidate_id.len() == 64
        && baseline_id.len() == 64
        && evaluator == EVALUATOR
        && !e.is_empty()
        && e.len() <= 4096
}

if !valid_promotion_args(&candidate_id, &baseline_id, evaluator, evidence_ref) {
    return Err(anyhow::anyhow!("invalid promotion arguments"));
}

Type guard

fn promotion_inputs_ok(candidate_id: &str, baseline_id: &str, evaluator: &str, evidence_ref: &str) -> bool {
    valid_promotion_args(candidate_id, baseline_id, evaluator, evidence_ref)
}

Try / catch

match store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, ...) {
    Ok(out) => { /* handled */ }
    Err(e) if e.to_string().contains("valid candidate ids, recorded-v1 evaluator") => {
        // correct evaluator string / id lengths / evidence size and retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling promote_harness with candidate_id.len() != 64 or baseline_id.len() != 64, evaluator != "recorded-v1", evidence_ref empty, or evidence_ref.len() > 4096.

Common situations: 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.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/30e0689e8c80aa03. Report an issue: GitHub.