{"record":{"id":"ae60efd1a250e3d8","repo":"AprilNEA/OpenLogi","slug":"could-not-pick-a-device-automatically-online-devices-list","errorCode":null,"errorMessage":"could not pick a device automatically.\n  online devices:\n{list}\n  pass --device <name> to choose one.","messagePattern":"could not pick a device automatically\\.\n  online devices:\n(.+?)\n  pass --device <name> to choose one\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/diag.rs","lineNumber":94,"sourceCode":"            out.push(Candidate { route, name });\n        }\n    }\n    Ok(out)\n}\n\n/// Build a helpful \"couldn't pick a device\" error that lists what *is* online.\nfn no_match_err(devices: &[Candidate], query: Option<&str>) -> anyhow::Error {\n    if devices.is_empty() {\n        return anyhow!(\"no online HID++ device found — is a Logi device paired and awake?\");\n    }\n    let list = devices\n        .iter()\n        .map(|c| format!(\"    - {} ({})\", c.name, c.route))\n        .collect::<Vec<_>>()\n        .join(\"\\n\");\n    match query {\n        Some(q) => anyhow!(\"no online device matches `--device {q}`.\\n  online devices:\\n{list}\"),\n        None => anyhow!(\n            \"could not pick a device automatically.\\n  online devices:\\n{list}\\n  \\\n             pass --device <name> to choose one.\"\n        ),\n    }\n}\n\n/// Pick the device a diag should run against.\n///\n/// Selection order:\n/// 1. If `query` is set, the first online device whose name contains it\n///    (case-insensitive) — lets the user disambiguate explicitly.\n/// 2. Else, if `required_features` is non-empty, the first online device whose\n///    HID++ feature table exposes *any* of them. This is what stops a\n///    mouse-only diag (DPI, SmartShift) from picking a paired keyboard when\n///    several devices are online — a real hazard on Bluetooth-direct setups\n///    where each device enumerates as its own inventory.\n/// 3. Else, the first online device (the original behaviour).\npub(crate) async fn select_device(","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/diag.rs#L76-L112","documentation":"Thrown by `no_match_err` when no `--device` query was given and automatic selection cannot proceed because the online candidate list does not resolve to a single device. The error prints all online devices and tells the user to pass `--device <name>`. This is the ambiguous-selection branch, distinct from the empty-list and query-mismatch branches.","triggerScenarios":"Running a diagnostic subcommand without `--device` while multiple HID++ devices are online and the automatic selection logic cannot disambiguate (the list is non-empty, so it is never the empty branch).","commonSituations":"A mouse and a keyboard both online; a device reachable via both receiver and direct-Bluetooth routes producing multiple candidates; scripted use that assumed exactly one device would be attached.","solutions":["Add `--device <name>` choosing one of the names printed in the error's `online devices:` list.","If multiple routes expose the same device, pick the specific route/name combination you intend.","In scripts, always pass `--device` explicitly rather than relying on automatic selection.","Take the other devices offline (or unplug the receiver) if you truly want auto-selection."],"exampleFix":"// before\n$ openlogi diag smartshift\n// error: could not pick a device automatically...\n// after\n$ openlogi diag smartshift --device \"MX Master 3S\"","handlingStrategy":"validation","validationCode":"// require --device when more than one candidate is online\nlet devices = enumerate_candidates()?;\nif devices.len() > 1 && query.is_none() {\n    eprintln!(\"multiple devices online; pass --device: {}\",\n        devices.iter().map(|d| d.name.as_str()).collect::<Vec<_>>().join(\", \"));\n    std::process::exit(2);\n}","typeGuard":null,"tryCatchPattern":"// auto-pick only when unambiguous, else surface the same guidance\nmatch select_device(&devices, None) {\n    Ok(d) => run(d),\n    Err(e) => { eprintln!(\"{e:#}\"); std::process::exit(2); } // usage error, user must pass --device\n}","preventionTips":["Always pass `--device` explicitly in scripts and CI — never rely on auto-selection.","Keep only one Logitech device connected when you intend to omit `--device`.","Name the specific route when a device appears via both receiver and Bluetooth.","Read the error's device list; it is the authoritative menu of valid values."],"tags":["cli","hidpp","device-selection"],"backgroundTag":"missing-required-argument","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"}