ruvnet/RuView · error · anyhow::Error
training failed: {e}
Error message
training failed: {e} What it means
SpecialistBank::train returned Err while building the mixture-of-specialists bank from enrollment anchors. In the library (wifi-densepose-calibration/src/bank.rs:58) the only error is CalibrationError::InsufficientSamples for an empty anchors slice — a case train-room already rejects earlier with its own 'no accepted anchors' bail — so this wrap is a defensive guard against future train() failure modes.
Source
Thrown at v2/crates/wifi-densepose-cli/src/room.rs:260
let raw = std::fs::read_to_string(&args.enrollment)
.map_err(|e| anyhow::anyhow!("cannot read {}: {e} — run `enroll` first", args.enrollment))?;
let mut data: EnrollmentData =
serde_json::from_str(&raw).map_err(|e| anyhow::anyhow!("invalid enrollment: {e}"))?;
if data.anchors.is_empty() {
bail!("no accepted anchors in {} — re-run enroll", args.enrollment);
}
if let Some(path) = &args.geometry {
let graw = std::fs::read_to_string(path)
.map_err(|e| anyhow::anyhow!("cannot read geometry {path}: {e}"))?;
let geometry: Vec<NodeGeometry> = serde_json::from_str(&graw).map_err(|e| {
anyhow::anyhow!("invalid geometry {path}: {e} (expected a JSON array of NodeGeometry records)")
})?;
data.session.record_geometry(geometry, now_unix());
}
let mut bank = SpecialistBank::train(&data.room_id, &data.baseline_id, &data.anchors, now_unix())
.map_err(|e| anyhow::anyhow!("training failed: {e}"))?;
match data.session.geometry() {
Some(g) if !g.is_empty() => {
bank = bank.with_geometry(g.to_vec());
eprintln!(
"[train-room] geometry: {} node(s) snapshotted into the bank (ADR-152 §2.1.1)",
bank.geometry.len()
);
}
_ => eprintln!(
"[train-room] no transceiver geometry recorded — bank will not support geometry conditioning (ADR-152 §2.1.2)"
),
}
std::fs::write(&args.output, bank.to_json().map_err(|e| anyhow::anyhow!("{e}"))?)
.map_err(|e| anyhow::anyhow!("cannot write {}: {e}", args.output))?;
eprintln!(
"[train-room] room='{}' trained {} specialists from {} anchors → {}",
bank.room_id,View on GitHub (pinned to 4685618388)
Solutions
- Read the {e} payload: InsufficientSamples names the kind and the have/need counts
- Re-run enroll to capture more accepted anchors (raise --attempts if prompts fail quality gates)
- If you changed bank.rs thresholds, align them with what enroll can realistically accept
- Keep the CLI and the calibration crate from the same build
Defensive patterns
Strategy: validation
Validate before calling
fn can_train_bank(anchors: &[AnchorFeature]) -> bool {
!anchors.is_empty()
} Prevention
- Ensure enroll accepts at least one anchor before train-room (its output prints got/total)
- After changing SpecialistBank::train thresholds, re-enroll to meet the new minimums
- Keep the CLI and calibration crate versions in lockstep
When it happens
Trigger: Unreachable via the current train-room path (the empty-anchor case is pre-checked); would resurface if SpecialistBank::train gains new validation minimums or if the CLI pre-check is removed.
Common situations: Seen after modifying bank.rs thresholds while reusing old enrollment files; version skew between the CLI and the calibration crate.
Related errors
- cannot bind UDP socket on {addr}: {e}
- calibration failed: {e}
- cannot write {output}: {e}
- cannot create output dir {}: {e}
- cannot bind UDP socket on {udp_addr}: {e}
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/0395c67eb50f8651.
Report an issue: GitHub.