{"record":{"id":"e2d925c2e0cb6a81","repo":"affaan-m/ECC","slug":"at-least-one-non-empty-kind-reference-is-require","errorCode":null,"errorMessage":"at least one non-empty {kind} reference is required","messagePattern":"at least one non-empty (.+?) reference is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/harness_eval.rs","lineNumber":261,"sourceCode":"        Ok(Self::new(\n            serde_json::from_str(&self.canonical_config)?,\n            self.trace_refs.clone(),\n            self.evidence_refs.clone(),\n        )?\n        .id)\n    }\n}\n\n#[derive(Serialize)]\nstruct CanonicalCandidateArtifact<'a> {\n    config: Value,\n    trace_refs: &'a [String],\n    evidence_refs: &'a [String],\n}\n\nfn normalize_refs(kind: &str, refs: Vec<String>) -> Result<Vec<String>> {\n    if refs.is_empty() || refs.iter().any(|reference| reference.trim().is_empty()) {\n        bail!(\"at least one non-empty {kind} reference is required\");\n    }\n    if refs.len() > 100 || refs.iter().any(|reference| reference.len() > 4096) {\n        bail!(\"{kind} references exceed bounded limits\");\n    }\n    let mut normalized = refs\n        .into_iter()\n        .map(|reference| reference.trim().to_string())\n        .collect::<Vec<_>>();\n    normalized.sort();\n    normalized.dedup();\n    Ok(normalized)\n}\n\nfn sha256_hex(bytes: &[u8]) -> String {\n    Sha256::digest(bytes)\n        .iter()\n        .map(|byte| format!(\"{byte:02x}\"))\n        .collect()","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/harness_eval.rs#L243-L279","documentation":"normalize_refs validates that the trace_refs/evidence_refs passed to HarnessCandidate::new contain at least one entry and that no entry is blank or whitespace-only. The library requires every candidate to carry at least one non-empty reference for its content address. An empty vector or a list containing \"\" or \"   \" triggers this error, with {kind} substituted by the parameter name (trace/evidence).","triggerScenarios":"HarnessCandidate::new called with trace_refs: vec![] or evidence_refs: vec![]; passing a list containing an empty string or whitespace-only entry such as vec![String::new()] or vec![\" \".into()]; programmatic construction from a config where a refs key was missing and defaulted to empty.","commonSituations":"Config file omits trace_refs/evidence_refs so an empty Vec is passed; a CI pipeline builds the refs list dynamically and a step produced no output; splitting a comma-separated string of refs yields an empty trailing element.","solutions":["Supply at least one meaningful (non-blank) reference in the refs vector before calling new.","Filter out blank entries before constructing: refs.into_iter().map(|s| s.trim().to_string()).filter(|s| !s.is_empty()).collect().","Fix the source config/script so the refs key is populated (e.g. ensure the artifact path or commit sha is generated).","Validate inputs at the call site with an early check that fails with a clearer message naming the missing ref kind."],"exampleFix":"// before\nlet candidate = HarnessCandidate::new(vec![], evidence_refs)?;\n\n// after\nlet trace_refs: Vec<String> = collected\n    .into_iter()\n    .map(|s| s.trim().to_string())\n    .filter(|s| !s.is_empty())\n    .collect();\nif trace_refs.is_empty() {\n    anyhow::bail!(\"no trace refs collected before building candidate\");\n}\nlet candidate = HarnessCandidate::new(trace_refs, evidence_refs)?;","handlingStrategy":"validation","validationCode":"fn valid_refs(refs: &[String]) -> bool {\n    !refs.is_empty() && refs.iter().all(|r| !r.trim().is_empty())\n}","typeGuard":"fn non_empty_refs(refs: Vec<String>) -> Option<Vec<String>> {\n    let cleaned: Vec<String> = refs.into_iter().map(|r| r.trim().to_string()).filter(|r| !r.is_empty()).collect();\n    (!cleaned.is_empty()).then_some(cleaned)\n}","tryCatchPattern":"match HarnessCandidate::new(trace_refs, evidence_refs) {\n    Ok(c) => proceed(c),\n    Err(e) if e.to_string().contains(\"non-empty\") => bail!(\"trace/evidence refs missing from config\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Trim and filter blank entries out of ref lists at the point of collection.","Fail fast in config loading if trace_refs/evidence_refs keys are absent.","Check pipeline step output is non-empty before building a candidate in CI."],"tags":["validation","empty-input","arguments"],"backgroundTag":"empty-required-field","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}