{"record":{"id":"994c459a89ca994a","repo":"ruvnet/RuView","slug":"cannot-read-geometry-path-e","errorCode":null,"errorMessage":"cannot read geometry {path}: {e}","messagePattern":"cannot read geometry (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v2/crates/wifi-densepose-cli/src/room.rs","lineNumber":252,"sourceCode":"}\n\n/// Execute `train-room`.\n///\n/// If the enrollment session carries a transceiver-geometry snapshot (recorded\n/// at enroll time or supplied here via `--geometry`), it is threaded into the\n/// bank (ADR-152 §2.1.1); a geometry-free enrollment still trains a valid bank.\npub async fn train_room(args: TrainRoomArgs) -> Result<()> {\n    let raw = std::fs::read_to_string(&args.enrollment)\n        .map_err(|e| anyhow::anyhow!(\"cannot read {}: {e} — run `enroll` first\", args.enrollment))?;\n    let mut data: EnrollmentData =\n        serde_json::from_str(&raw).map_err(|e| anyhow::anyhow!(\"invalid enrollment: {e}\"))?;\n    if data.anchors.is_empty() {\n        bail!(\"no accepted anchors in {} — re-run enroll\", args.enrollment);\n    }\n\n    if let Some(path) = &args.geometry {\n        let graw = std::fs::read_to_string(path)\n            .map_err(|e| anyhow::anyhow!(\"cannot read geometry {path}: {e}\"))?;\n        let geometry: Vec<NodeGeometry> = serde_json::from_str(&graw).map_err(|e| {\n            anyhow::anyhow!(\"invalid geometry {path}: {e} (expected a JSON array of NodeGeometry records)\")\n        })?;\n        data.session.record_geometry(geometry, now_unix());\n    }\n\n    let mut bank = SpecialistBank::train(&data.room_id, &data.baseline_id, &data.anchors, now_unix())\n        .map_err(|e| anyhow::anyhow!(\"training failed: {e}\"))?;\n    match data.session.geometry() {\n        Some(g) if !g.is_empty() => {\n            bank = bank.with_geometry(g.to_vec());\n            eprintln!(\n                \"[train-room] geometry: {} node(s) snapshotted into the bank (ADR-152 §2.1.1)\",\n                bank.geometry.len()\n            );\n        }\n        _ => eprintln!(\n            \"[train-room] no transceiver geometry recorded — bank will not support geometry conditioning (ADR-152 §2.1.2)\"","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/v2/crates/wifi-densepose-cli/src/room.rs#L234-L270","documentation":"train-room failed to read the optional --geometry file (std::fs::read_to_string). It can only occur when --geometry was explicitly passed; the io::Error is usually NotFound or permission denied, i.e. a wrong or stale path in the flag.","triggerScenarios":"Passing --geometry with a typo'd or moved path; the file deleted between enroll and train; unreadable permissions; a non-UTF-8 file at the path.","commonSituations":"Ops scripts referencing a geometry snapshot that moved or was renamed; assuming geometry is mandatory when the command explicitly supports a geometry-free path.","solutions":["Verify the path exists and is readable","Omit --geometry to train a geometry-free bank (explicitly supported per the code comment)","Regenerate the geometry snapshot if the source is gone"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn geometry_file_ok(path: &str) -> bool {\n    std::path::Path::new(path).is_file() && std::fs::read_to_string(path).is_ok()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat --geometry as optional: omit it rather than passing a guessed path","Pin geometry file paths in one config location","Regenerate geometry snapshots with the room survey, not ad hoc"],"tags":["rust","filesystem","geometry","cli"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}