AprilNEA/OpenLogi · error
lumens must be in the supported range
Error message
lumens must be in the supported range {}..={} with step {} What it means
Raised in `set_brightness` when `--lumens` is given but the value is outside the device's advertised brightness range or the device's range is not expressed in lumens. The CLI validates against `range.contains(lumens)` and `range.unit() == Lumens` before sending a BrightnessNative command, embedding min/max/step in the message.
Solutions
- Read the supported range from the error text and pass a value within min..=max honoring step
- Use `--percent` instead of `--lumens` for unit-independent brightness control
- Check `openlogi list`/device docs for the actual native range before scripting values
Example fix
// before openlogi light brightness --lumens 500 // after openlogi light brightness --percent 50 # or use a value inside the advertised range, e.g. min=20 max=200 step=10: openlogi light brightness --lumens 200
Defensive patterns
Strategy: validation
Validate before calling
let range = &caps.brightness.expect("checked earlier");
if !range.contains(lumens) || range.unit() != LightValueUnit::Lumens {
anyhow::bail!("lumens {} outside {}..={} step {}", lumens, range.min(), range.max(), range.step());
} Type guard
fn lumens_in_range(range: &BrightnessRange, v: u32) -> bool {
range.unit() == LightValueUnit::Lumens && range.contains(v)
} Try / catch
match set_brightness(args).await {
Ok(()) => (),
Err(e) if e.to_string().contains("supported range") => {
eprintln!("{}\nUse --percent instead for unit-safe control.", e);
}
Err(e) => return Err(e),
} Prevention
- Prefer `--percent` over `--lumens` unless you need native precision
- Parse min/max/step from the error or `openlogi list` before sending values
- Clamp and step-align scripted lumen values to the advertised range
When it happens
Trigger: `openlogi light ... brightness --lumens N` where N < range.min(), N > range.max(), N violates range.step(), or the device's brightness range uses a different unit than lumens.
Common situations: Guessing lumen values instead of reading the device's advertised range from the error message; confusing percent vs native lumen interfaces; typos like 1000 instead of 100.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- saved contribution profile does not match its resumable…
- --id must be a nonempty synthetic path component
- --id must be one synthetic path component without separators
- --name must be a nonempty synthetic device name
- --output directory name must exactly equal --id
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/1ff7f5f63bdd5d06.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/light.rs:131
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"),
};
apply(device, command).await
}
async fn set_temperature(args: TemperatureArgs) -> Result<()> {
let devices = standalone().await?;
let device = select(&devices, args.device.device.as_deref())?;
apply(device, LightCommand::TemperatureKelvin(args.kelvin)).awaitView on GitHub (pinned to e846e6f4b4)