affaan-m/ECC · error · anyhow::Error
candidate alias collision with physical candidate id
Error message
candidate alias collision with physical candidate id
What it means
Thrown by register_harness_alias when the proposed alias_id is already present as a physical candidate id in the harness_candidates table. The store forbids an alias from shadowing a real candidate id so the id namespace stays unambiguous: a lookup of alias_id must not silently resolve to two different things.
Source
Thrown at ecc2/src/session/store.rs:5307
}
}
impl StateStore {
fn register_harness_alias(
tx: &rusqlite::Transaction<'_>,
alias_id: &str,
candidate_id: &str,
) -> Result<()> {
if tx
.query_row(
"SELECT 1 FROM harness_candidates WHERE id = ?1",
[alias_id],
|_| Ok(()),
)
.optional()?
.is_some()
{
anyhow::bail!("candidate alias collision with physical candidate id");
}
let existing = tx
.query_row(
"SELECT candidate_id FROM harness_candidate_aliases WHERE alias_id = ?1",
[alias_id],
|row| row.get::<_, String>(0),
)
.optional()?;
if let Some(existing) = existing {
if existing != candidate_id {
anyhow::bail!("candidate alias collision with different immutable target");
}
return Ok(());
}
tx.execute(
"INSERT INTO harness_candidate_aliases (alias_id, candidate_id, id_version, created_at) VALUES (?1, ?2, 2, ?3)",
rusqlite::params![alias_id, candidate_id, chrono::Utc::now().to_rfc3339()],
)?;View on GitHub (pinned to 01e15490f0)
Solutions
- Pick an alias_id that is provably not already a physical candidate id (query harness_candidates first).
- If the alias_id must equal that value, drop or rename the physical candidate row before registering the alias.
- Namespace aliases distinctly from physical ids (e.g. a prefix) so the two sets cannot overlap by construction.
Example fix
// before
store.register_harness_alias(&tx, &legacy_id, &candidate.id)?;
// after
let taken: Option<i64> = tx.query_row(
"SELECT 1 FROM harness_candidates WHERE id = ?1",
[&legacy_id], |_| Ok(1)).optional()?;
if taken.is_some() {
anyhow::bail!("refusing to alias legacy_id {legacy_id}: it is a physical candidate id");
}
store.register_harness_alias(&tx, &legacy_id, &candidate.id)?; Defensive patterns
Strategy: validation
Validate before calling
fn alias_is_physical_candidate(tx: &rusqlite::Transaction, alias_id: &str) -> Result<bool> {
let exists: Option<i64> = tx.query_row(
"SELECT 1 FROM harness_candidates WHERE id = ?1",
[alias_id], |_| Ok(1)).optional()?;
Ok(exists.is_some())
}
// before register_harness_alias:
if alias_is_physical_candidate(&tx, alias_id)? {
return Err(anyhow::anyhow!("alias_id {alias_id} is a physical candidate id; choose a distinct alias"));
} Type guard
fn safe_alias_id(tx: &rusqlite::Transaction, alias_id: &str) -> bool {
!tx.query_row("SELECT 1 FROM harness_candidates WHERE id = ?1", [alias_id], |_| Ok(1))
.optional().ok().flatten().is_some()
} Try / catch
match store.register_harness_alias(&tx, alias_id, candidate_id) {
Ok(()) => { /* registered */ }
Err(e) if e.to_string().contains("alias collision with physical candidate id") => {
// choose a different alias_id and retry, or surface to caller
}
Err(e) => return Err(e),
} Prevention
- Keep alias ids and physical candidate ids in disjoint namespaces (e.g. prefix aliases) so they can never collide by construction.
- When migrating legacy ids, cross-check each legacy id against harness_candidates before registering it as an alias.
- Add a unique constraint or trigger so the DB itself rejects an alias equal to a physical candidate id.
When it happens
Trigger: Calling register_harness_alias(tx, alias_id, candidate_id) where SELECT 1 FROM harness_candidates WHERE id = alias_id returns a row. Typical when a legacy id being registered as an alias happens to equal an already-stored v2 content-addressed candidate id.
Common situations: Migrating a legacy id scheme where a legacy id was itself promoted to a v2 candidate id; reusing one 64-char hex value as both a physical candidate and an alias target; two subsystems deriving the same digest for different purposes.
Related errors
- candidate alias collision with different immutable target
- candidate id collision with different immutable content
- missing harness health evidence integrity metadata
- incomplete harness health evidence integrity metadata
- harness health evidence integrity verification failed
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/dc48d457f7ad7e7b.
Report an issue: GitHub.