AprilNEA/OpenLogi · error

selected light did not advertise capabilities

Error message

selected light did not advertise capabilities

What it means

Raised in `set_brightness` when the selected device's snapshot has `light_capabilities: None`, meaning the device did not advertise any light (illumination) capabilities during probing. The CLI refuses to guess capabilities and requires the device to expose its light feature set before any brightness or temperature command.

Solutions

  1. Verify the selected device actually supports lighting (check `openlogi list` output for light capabilities)
  2. Power-cycle or wake the device and re-enumerate so capabilities are probed again
  3. Re-pair or reconnect the device if capability probing consistently returns nothing
  4. Use the correct subcommand family for the device type you actually attached
Defensive patterns

Strategy: type-guard

Validate before calling

let device = select(&devices, name)?;
if device.light_capabilities.is_none() {
    anyhow::bail!("{} exposes no light capabilities", device.display_name);
}

Type guard

fn light_caps(d: &Device) -> Option<&LightCapabilities> {
    d.light_capabilities.as_ref()
}

Try / catch

match set_brightness(args).await {
    Ok(()) => (),
    Err(e) if e.to_string().contains("did not advertise capabilities") => {
        eprintln!("This device has no lighting features; check `openlogi list`.");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `openlogi light ... brightness` (or related light subcommands) targeting a device whose enumerated snapshot lacks light_capabilities — the device is not a light-capable product or the capability probe failed at enumeration.

Common situations: Pointing a light subcommand at a mouse or keyboard instead of a light-equipped product; the device was probed while asleep so capability blocks were never read; firmware/HID++ feature discovery failed for the attached unit.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13). Data as JSON: /api/errors/b33769f137f96b23. Report an issue: GitHub.

Appendix: source

Thrown at crates/openlogi-cli/src/cmd/light.rs:123

            }
            println!("  power: {}", if caps.power { "yes" } else { "no" });
        }
    }
    Ok(())
}

async fn set_power(query: Option<&str>, enabled: bool) -> Result<()> {
    let devices = standalone().await?;
    let device = select(&devices, query)?;
    apply(device, LightCommand::Power(enabled)).await
}

async fn set_brightness(args: BrightnessArgs) -> Result<()> {
    let devices = standalone().await?;
    let device = select(&devices, args.device.device.as_deref())?;
    let caps = device
        .light_capabilities
        .ok_or_else(|| anyhow!("selected light did not advertise capabilities"))?;
    let range = caps
        .brightness
        .ok_or_else(|| anyhow!("selected light does not support brightness"))?;
    let command = match (args.percent, args.lumens) {
        (Some(percent), None) => LightCommand::BrightnessPercent(percent),
        (None, Some(lumens)) => {
            if range.unit() != LightValueUnit::Lumens || !range.contains(lumens) {
                return Err(anyhow!(
                    "lumens must be in the supported range {}..={} with step {}",
                    range.min(),
                    range.max(),
                    range.step()
                ));
            }
            LightCommand::BrightnessNative(lumens)
        }
        (None, None) => return Err(anyhow!("pass either --percent or --lumens")),
        (Some(_), Some(_)) => unreachable!("clap enforces the argument conflict"),

View on GitHub (pinned to e846e6f4b4)