affaan-m/ECC · error · anyhow::Error
valid candidate id and bounded activation evidence reference
Error message
valid candidate id and bounded activation evidence reference are required
What it means
activate_initial_harness enforces input bounds: candidate_id must be exactly 64 chars (the v2 hex digest length) and evidence_ref must be non-empty after trimming and at most 4096 chars. Failing any one bails with this single aggregate message.
Source
Thrown at ecc2/src/session/store.rs:5401
self.conn.execute(
"INSERT INTO harness_candidates (id, canonical_config_json, trace_refs_json, evidence_refs_json, created_at)
VALUES (?1, ?2, ?3, ?4, ?5) ON CONFLICT(id) DO NOTHING",
rusqlite::params![candidate.id, candidate.canonical_config, trace_json, evidence_json, chrono::Utc::now().to_rfc3339()],
)?;
let stored: (String, String, String) = self.conn.query_row(
"SELECT canonical_config_json, trace_refs_json, evidence_refs_json FROM harness_candidates WHERE id = ?1",
[&candidate.id],
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
)?;
if stored != expected {
anyhow::bail!("candidate id collision with different immutable content");
}
Ok(())
}
pub fn activate_initial_harness(&self, candidate_id: &str, evidence_ref: &str) -> Result<()> {
if candidate_id.len() != 64 || evidence_ref.trim().is_empty() || evidence_ref.len() > 4096 {
anyhow::bail!(
"valid candidate id and bounded activation evidence reference are required"
);
}
let tx = self.conn.unchecked_transaction()?;
let stored_candidate_id = Self::resolve_harness_candidate_id(&tx, candidate_id)?;
if tx
.query_row(
"SELECT candidate_id FROM active_harness_config WHERE slot = 'default'",
[],
|row| row.get::<_, String>(0),
)
.optional()?
.is_some()
{
anyhow::bail!("an active harness configuration already exists");
}
let now = chrono::Utc::now().to_rfc3339();
tx.execute("INSERT INTO active_harness_config (slot, candidate_id, updated_at) VALUES ('default', ?1, ?2)", rusqlite::params![stored_candidate_id, now])?;View on GitHub (pinned to 01e15490f0)
Solutions
- Validate candidate_id is exactly 64 hex characters before calling.
- Trim evidence_ref and assert 1 <= len <= 4096.
- Store large evidence externally (object store, file) and pass only a short reference URI/digest.
Example fix
// before
store.activate_initial_harness(&candidate_id, &evidence_ref)?;
// after
fn is_v2_id(s: &str) -> bool {
s.len() == 64 && s.bytes().all(|b| b.is_ascii_hexdigit())
}
if !is_v2_id(&candidate_id) {
anyhow::bail!("candidate_id must be a 64-char hex digest");
}
let evidence_ref = evidence_ref.trim();
if evidence_ref.is_empty() || evidence_ref.len() > 4096 {
anyhow::bail!("evidence_ref must be 1..=4096 chars");
}
store.activate_initial_harness(&candidate_id, evidence_ref)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_v2_id(s: &str) -> bool {
s.len() == 64 && s.bytes().all(|b| b.is_ascii_hexdigit())
}
let evidence_ref = evidence_ref.trim();
if !is_v2_id(&candidate_id)
|| evidence_ref.is_empty()
|| evidence_ref.len() > 4096
{
return Err(anyhow::anyhow!("invalid activation arguments"));
}
store.activate_initial_harness(&candidate_id, evidence_ref)?; Type guard
fn valid_activation_args(candidate_id: &str, evidence_ref: &str) -> bool {
let e = evidence_ref.trim();
candidate_id.len() == 64 && !e.is_empty() && e.len() <= 4096
} Try / catch
match store.activate_initial_harness(&candidate_id, &evidence_ref) {
Ok(()) => { /* activated */ }
Err(e) if e.to_string().contains("valid candidate id and bounded activation") => {
// fix the candidate_id length or the evidence_ref size and retry
}
Err(e) => return Err(e),
} Prevention
- Centralize the 64-char hex-id check in one helper and use it at every entry point.
- Keep evidence_ref a short reference (URI/digest), never an inline payload.
- Add a unit test that asserts the exact bounds (64, 1..=4096).
When it happens
Trigger: Calling activate_initial_harness(candidate_id, evidence_ref) where candidate_id.len() != 64, evidence_ref.trim().is_empty(), or evidence_ref.len() > 4096.
Common situations: Passing a legacy (non-64-char) id; passing a full URL or JSON blob as evidence that exceeds 4096 chars; whitespace-only evidence; passing an Option<None> rendered as empty.
Related errors
- valid candidate ids, recorded-v1 evaluator, and bounded evid
- health evidence does not match candidate and evaluator
- harness health evidence exceeds integrity verification bound
- At least one guided harness must be selected
- The all/* harness selection cannot be combined with other se
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/f366af8e35a747ad.
Report an issue: GitHub.