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

  1. Read the {e} payload: InsufficientSamples names the kind and the have/need counts
  2. Re-run enroll to capture more accepted anchors (raise --attempts if prompts fail quality gates)
  3. If you changed bank.rs thresholds, align them with what enroll can realistically accept
  4. 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

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


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/0395c67eb50f8651. Report an issue: GitHub.