ruvnet/RuView · error

cannot read : — run `enroll` first

Error message

cannot read {}: {e} — run `enroll` first

What it means

train-room failed to std::fs::read_to_string the --enrollment JSON file; the message directs to 'run enroll first'. Typical io::Error kinds: NotFound (no enroll run yet or wrong path), permission denied, or InvalidData when the file is not valid UTF-8 — e.g. a binary baseline passed by mistake.

Solutions

  1. Run enroll and use the path it prints
  2. Pass the enrollment .json file, not the binary baseline
  3. Prefer absolute paths or a fixed working directory
  4. Fix read permissions if the file exists

Example fix

// before
$ ruview train-room --enrollment ./baseline.bin   # cannot read — run `enroll` first

// after
$ ruview enroll --output ./artifacts/enrollment.json
$ ruview train-room --enrollment ./artifacts/enrollment.json
Defensive patterns

Strategy: validation

Validate before calling

fn enrollment_readable(path: &str) -> bool {
    std::path::Path::new(path).is_file() && std::fs::read_to_string(path).is_ok()
}

Prevention

When it happens

Trigger: Running train-room before enroll produced the file; --enrollment pointing at the binary baseline instead of enrollment JSON; non-UTF-8 content; unreadable permissions.

Common situations: Workflow ordering mistakes across the calibrate, enroll, train-room chain; artifact-type mixups; relative paths breaking across working directories.

Related errors


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

Appendix: source

Thrown at v2/crates/wifi-densepose-cli/src/room.rs:243

    pub enrollment: String,
    /// Output specialist-bank file.
    #[arg(long, default_value = "./room-bank.json")]
    pub output: String,
    /// Optional transceiver-geometry file: a JSON array of `NodeGeometry`
    /// records (ADR-152 §2.1.1). Recorded into the enrollment session before
    /// training so the bank carries the layout it was trained under.
    #[arg(long)]
    pub geometry: Option<String>,
}

/// Execute `train-room`.
///
/// If the enrollment session carries a transceiver-geometry snapshot (recorded
/// at enroll time or supplied here via `--geometry`), it is threaded into the
/// bank (ADR-152 §2.1.1); a geometry-free enrollment still trains a valid bank.
pub async fn train_room(args: TrainRoomArgs) -> Result<()> {
    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() {

View on GitHub (pinned to 4685618388)