AprilNEA/OpenLogi · error
no Logitech camera found
Error message
no Logitech camera found
What it means
`snapshot run` needs a camera unique id: if `--camera` is not given it takes the first camera from `openlogi_camera::enumerate_cameras()`. When enumeration returns an empty list, the `ok_or_else` turns the `None` into this anyhow error. It means no Logitech UVC camera was visible to the camera layer at all.
Solutions
- Plug in the Logitech camera (or confirm it is a Logitech model, not another vendor).
- Pass the explicit device with `--camera <unique-id>` after confirming its id via enumeration.
- Close apps holding the camera exclusively, then retry.
- On macOS, grant Camera permission to the process in System Settings → Privacy & Security → Camera.
- Replug the camera / try another USB port to rule out enumeration flakiness.
Example fix
// before $ openlogi snapshot out.png error: no Logitech camera found // after — plug the camera in, or target it explicitly once its id is known $ openlogi snapshot out.png --camera "usb:046d:085e"
Defensive patterns
Strategy: fallback
Validate before calling
let cameras = openlogi_camera::enumerate_cameras();
if cameras.is_empty() {
eprintln!("no Logitech camera visible; check connection/permissions");
return Ok(());
} Try / catch
// snapshot::run returns anyhow::Result; intercept the enumeration failure
match snapshot_run(args) {
Err(e) if e.to_string().contains("no Logitech camera found") => {
eprintln!("connect a Logitech camera or pass --camera <unique-id>");
}
other => other?,
} Prevention
- Enumerate cameras and fail fast with a friendly message before attempting capture.
- On macOS confirm the Camera (TCC) permission is granted to the process.
- Check for apps holding the camera exclusively before scripting captures.
When it happens
Trigger: Running the `snapshot` command without `--camera` while `enumerate_cameras()` returns zero Logitech cameras (the iterator's `.next()` is `None`).
Common situations: No camera plugged in or it is a non-Logitech webcam; the camera is claimed exclusively by another app (Zoom/Teams) or the OS; on macOS the Camera (TCC) permission was denied so enumeration is empty; a USB hub/dock dropped the device.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- no Logitech camera found
- {e}
- unknown control ( )
- failed to enumerate HID++ devices for direct fixture capture
- . Candidates
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/f45c06aaff7cc018.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/snapshot.rs:30
#[derive(Debug, Args)]
pub struct SnapshotArgs {
/// Output PNG path.
#[arg(default_value = "snapshot.png")]
pub path: String,
/// Capture from the camera with this unique id (default: first Logitech).
#[arg(long)]
pub camera: Option<String>,
}
pub fn run(args: SnapshotArgs) -> Result<()> {
let unique_id = match args.camera {
Some(id) => id,
None => openlogi_camera::enumerate_cameras()
.into_iter()
.next()
.map(|camera| camera.unique_id)
.ok_or_else(|| anyhow!("no Logitech camera found"))?,
};
println!("capturing one frame from {unique_id} …");
let frame = openlogi_camera::capture_frame(&unique_id, Duration::from_secs(5))
.map_err(|e| anyhow!("{e}"))?;
// Frames are stored BGRA (gpui's order); PNG wants RGBA, so swap R/B once.
let mut rgba = frame.bgra;
for px in rgba.as_chunks_mut::<4>().0 {
px.swap(0, 2);
}
write_png(&args.path, frame.width, frame.height, &rgba)
.with_context(|| format!("writing {}", args.path))?;
println!("wrote {}x{} → {}", frame.width, frame.height, args.path);
Ok(())
}
fn write_png(path: &str, width: u32, height: u32, rgba: &[u8]) -> Result<()> {
let file = std::fs::File::create(path)?;View on GitHub (pinned to e846e6f4b4)