{"record":{"id":"e8e96448750ef09f","repo":"AprilNEA/OpenLogi","slug":"failed-to-enumerate-hid-devices-for-direct-fixture-capture","errorCode":null,"errorMessage":"failed to enumerate HID++ devices for direct fixture capture","messagePattern":"failed to enumerate HID\\+\\+ devices for direct fixture capture","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/record_case.rs","lineNumber":273,"sourceCode":"         cassette before committing it.\"\n    );\n    Ok(())\n}\n\npub(super) async fn prepare_contribution_target(selector: Option<&str>) -> Result<CaptureTarget> {\n    let agent_guard = acquire_capture_ownership().await?;\n    eprintln!(\n        \"warning: fixture case capture reads hardware directly with this CLI process's own HID \\\n         permission and identity, not the OpenLogi agent\"\n    );\n    eprintln!(\n        \"warning: discovery may enable wireless notifications and request arrival reports on \\\n         connected receivers before target selection; notification flags are not restored. \\\n         Captured operations do not change device settings or pairings.\"\n    );\n    let inventories = openlogi_hid::enumerate()\n        .await\n        .map_err(|_| anyhow!(\"failed to enumerate HID++ devices for direct fixture capture\"))?;\n    let candidates = online_targets(&inventories);\n    let target = target_selection::select_target(&candidates, selector)?;\n    Ok(CaptureTarget {\n        target,\n        _agent_guard: agent_guard,\n    })\n}\n\npub(super) async fn capture_for_contribution(\n    operation: FixtureOperation,\n    target: &CaptureTarget,\n    name: &str,\n    channel: &str,\n    capacity: usize,\n    identity_plan: &HidCassetteIdentityPlan,\n) -> Result<HidCassette> {\n    let (recording, observation) = capture(operation, target.route(), capacity).await?;\n    let candidates = audit::sanitize_recording_with_plan(recording, name, channel, identity_plan)?;","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/record_case.rs#L255-L291","documentation":"`prepare_contribution_target` enumerates HID++ devices directly via `openlogi_hid::enumerate()` to pick a capture target for direct fixture capture. Any enumeration failure is collapsed into this error because capture cannot proceed without a device list; no candidates can be built.","triggerScenarios":"`openlogi_hid::enumerate()` returns `Err` before target selection — typically the backend cannot open/claim HID device files, or the OS denies access (Linux: no permission on `/dev/hidraw*`; macOS: missing Input Monitoring permission for the CLI).","commonSituations":"Running the record command without `sudo`/udev rules on Linux, running the macOS binary from a terminal without Input Monitoring granted, another process (the agent) holding the device exclusively, or no HID transport backend available.","solutions":["Fix the underlying enumeration failure (check `openlogi list` for a more detailed error)","On Linux: add udev rules or run with sufficient privileges for hidraw access","On macOS: grant Input Monitoring permission to the terminal/binary, per docs/DEVELOPMENT.md","Stop the running agent if it holds devices exclusively, or use the agent-backed capture path instead of direct capture","Confirm a device is actually connected and is an HID++ device"],"exampleFix":"// before (Linux, permission denied on hidraw)\nopenlogi fixture record-case ...\n// after\nsudo cp packaging/99-openlogi.rules /etc/udev/rules.d/ && sudo udevadm control --reload && sudo udevadm trigger\nopenlogi fixture record-case ...","handlingStrategy":"fallback","validationCode":"// check direct HID access before starting capture\nmatch openlogi_hid::enumerate().await {\n    Ok(inv) if !inv.is_empty() => println!(\"{} HID++ device(s) reachable\", inv.len()),\n    Ok(_) => eprintln!(\"no HID++ devices visible; connect a device\"),\n    Err(e) => eprintln!(\"enumeration unavailable: {e}; fix permissions or use agent-backed capture\"),\n}","typeGuard":null,"tryCatchPattern":"match prepare_contribution_target(...).await {\n    Ok(target) => capture(target),\n    Err(e) if e.to_string().contains(\"failed to enumerate\") =>\n        eprintln!(\"{e:#}; grant hidraw/Input Monitoring access or use the agent path\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Install udev rules / run with adequate privileges on Linux before hardware commands","Grant Input Monitoring to the CLI's host app on macOS once, per docs","Stop the agent (or use agent-backed capture) to avoid exclusive device contention","Verify with `openlogi list` that devices enumerate before long capture sessions"],"tags":["cli","fixture","hid","enumeration","permissions"],"backgroundTag":"file-open-failed","analyzedSha":"e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8","analyzedAt":"2026-09-13T03:07:16.451Z","contentChangedAt":"2026-09-13T03:07:16.451Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}