AprilNEA/OpenLogi · error
--channel must not be empty
Error message
--channel must not be empty
What it means
`validate_metadata` rejects a `record-case` invocation whose `--channel` value is empty or only whitespace. The channel identifies which HID++ reporting channel the case was captured on and must be non-empty to sanitize and replay the recording.
Solutions
- Pass a concrete channel value, e.g. `--channel short-hidpp` or `--channel long-hidpp`
- In scripts, require the variable: `: "${CHANNEL:?CHANNEL must be set}"`
- Validate/trim upstream inputs before building the CLI invocation
Example fix
// before
openlogi fixture record-case --channel "$CHANNEL" # CHANNEL blank
// after
: "${CHANNEL:?CHANNEL must be set}"
openlogi fixture record-case --channel "$CHANNEL" Defensive patterns
Strategy: validation
Validate before calling
if channel.trim().is_empty() {
return Err("--channel must be a non-empty channel identifier");
} Prevention
- Always pass an explicit --channel in scripts
- Guard channel variables with ${CHANNEL:?msg}
- Trim and validate inputs before building the command line
When it happens
Trigger: Invoking `openlogi fixture record-case --channel ""` or `--channel " "`, typically from a script where the channel variable is unset or blank.
Common situations: CI scripts with a missing CHANNEL env var; hand-editing a command line and deleting the channel value; generating invocations from a template where an optional field was dropped.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- --name must not be empty
- --id must be a nonempty synthetic identifier
- --name must be a nonempty synthetic profile name
- saved contribution profile does not match its resumable…
- --id must be a nonempty synthetic path component
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/e5bbdcce2c1bb1a1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/record_case.rs:300
pub(super) async fn capture_for_contribution(
operation: FixtureOperation,
target: &CaptureTarget,
name: &str,
channel: &str,
capacity: usize,
identity_plan: &HidCassetteIdentityPlan,
) -> Result<HidCassette> {
let (recording, observation) = capture(operation, target.route(), capacity).await?;
let candidates = audit::sanitize_recording_with_plan(recording, name, channel, identity_plan)?;
replay::select_self_replaying(operation, &target.target, &observation, candidates).await
}
fn validate_metadata(args: &RecordCaseArgs) -> Result<()> {
if args.name.trim().is_empty() {
bail!("--name must not be empty");
}
if args.channel.trim().is_empty() {
bail!("--channel must not be empty");
}
Ok(())
}
async fn acquire_capture_ownership() -> Result<InstanceGuard> {
// The agent acquires this same lock before any HID I/O. An endpoint probe
// alone misses both early startup and a relaunch after the probe returns.
let guard = single_instance::acquire("agent.lock").context(
"refusing direct fixture capture: could not acquire agent.lock; \
stop the OpenLogi agent and any other fixture capture before retrying",
)?;
match tokio::time::timeout(AGENT_PROBE_TIMEOUT, client::connect()).await {
Ok(Err(ConnectError::Endpoint(error))) if endpoint_is_unreachable(&error) => Ok(guard),
Ok(Ok(_) | Err(ConnectError::Handshake(_) | ConnectError::Endpoint(_))) | Err(_) => bail!(
"refusing direct fixture capture because the agent endpoint is active or accepted a \
connection without completing a healthy handshake; this command uses the CLI's own \
HID permission and identity, so stop the OpenLogi agent before retrying"
),View on GitHub (pinned to e846e6f4b4)