affaan-m/ECC · error
baseline is not the active harness configuration
Error message
baseline is not the active harness configuration
What it means
Promotion is only evaluated against the configuration that is currently active in slot 'default'. The store reads the active candidate_id and requires it to equal the stored baseline_id from the call; if the active configuration has moved on (someone else promoted, or the wrong baseline was named), the evaluation is refused so a stale baseline is never silently replaced.
Solutions
- Read the current active id (active_harness_config, slot 'default') immediately before the call and use it as baseline_id.
- Retry the evaluation with the actual current active configuration as the baseline (the compare-and-swap design assumes you re-base on current state).
- Serialize promotions through a single coordinator/lock if multiple processes promote concurrently.
- Audit harness_eval_audit for recent promotion events to understand who changed the active configuration before your call.
Example fix
// before: hardcoded stale baseline
store.evaluate_promote_and_health_check(&cand, &old_baseline, ...)?;
// after: re-base on the live active id
let current = store.active_harness_id()?.ok_or_else(|| anyhow!("no active baseline"))?;
store.evaluate_promote_and_health_check(&cand, ¤t, ...)?; Defensive patterns
Strategy: retry
Validate before calling
// Re-base on the live active configuration immediately before promoting
let current_baseline = store.active_harness_id()?
.ok_or_else(|| anyhow!("no active baseline configuration"))?;
// pass current_baseline as baseline_id, not a cached/stale id Try / catch
match store.evaluate_promote_and_health_check(&cand, &baseline, ...) {
Err(e) if e.to_string().contains("baseline is not the active harness configuration") => {
let current = store.active_harness_id()?.unwrap();
store.evaluate_promote_and_health_check(&cand, ¤t, ...)?
}
other => other?,
} Prevention
- Read the active id at promotion time instead of caching it from earlier in the run
- Serialize promotions through one job/lock to avoid racing operators or CI pipelines
- Review harness_eval_audit when this error occurs to see who changed the active slot
When it happens
Trigger: Calling evaluate_promote_and_health_check with baseline_id that differs from the candidate currently recorded in active_harness_config (slot 'default'), typically after another promotion already changed the active configuration.
Common situations: Concurrent promotions where another process promoted a candidate between your snapshot and your call; passing the candidate you think is deployed rather than reading the actual active id; running a scripted promotion twice — the second run's baseline is now outdated.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- an active harness configuration already exists
- atomic promotion compare-and-swap failed
- atomic rollback compare-and-swap failed
- candidate id collision with different immutable content
- claim cannot grant another dispatch
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/0b4fbeafb3ec8a8d.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/store.rs:5490
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");
}
let now = chrono::Utc::now().to_rfc3339();
if !comparison.passed {
tx.execute("INSERT INTO harness_evaluations (candidate_id, baseline_id, evaluator, samples_json, policy_json, comparison_json, evidence_ref, legacy_unverifiable, created_at) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, 0, ?8)", rusqlite::params![stored_candidate_id, stored_baseline_id, evaluator, serde_json::to_string(samples)?, serde_json::to_string(&policy)?, serde_json::to_string(&comparison)?, evidence_ref, now])?;
let evaluation_id = tx.last_insert_rowid();
tx.execute("INSERT INTO harness_eval_audit (event_type, candidate_id, prior_candidate_id, evaluation_id, evidence_ref, legacy_unverifiable, created_at) VALUES ('promotion_rejected', ?1, ?2, ?3, ?4, 0, ?5)", rusqlite::params![stored_candidate_id, stored_baseline_id, evaluation_id, evidence_ref, now])?;
tx.commit()?;
return Ok(HarnessPromotionOutcome {
evaluation_id: Some(evaluation_id),
promoted: false,
rolled_back: false,
failures: comparison.failures,
});
}
let changed = tx.execute("UPDATE active_harness_config SET candidate_id = ?1, updated_at = ?2 WHERE slot = 'default' AND candidate_id = ?3", rusqlite::params![stored_candidate_id, now, stored_baseline_id])?;
if changed != 1 {
anyhow::bail!("atomic promotion compare-and-swap failed");
}View on GitHub (pinned to 8321021c54)