{"record":{"id":"e5bbdcce2c1bb1a1","repo":"AprilNEA/OpenLogi","slug":"channel-must-not-be-empty","errorCode":null,"errorMessage":"--channel must not be empty","messagePattern":"--channel must not be empty","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/record_case.rs","lineNumber":300,"sourceCode":"pub(super) async fn capture_for_contribution(\n    operation: FixtureOperation,\n    target: &CaptureTarget,\n    name: &str,\n    channel: &str,\n    capacity: usize,\n    identity_plan: &HidCassetteIdentityPlan,\n) -> Result<HidCassette> {\n    let (recording, observation) = capture(operation, target.route(), capacity).await?;\n    let candidates = audit::sanitize_recording_with_plan(recording, name, channel, identity_plan)?;\n    replay::select_self_replaying(operation, &target.target, &observation, candidates).await\n}\n\nfn validate_metadata(args: &RecordCaseArgs) -> Result<()> {\n    if args.name.trim().is_empty() {\n        bail!(\"--name must not be empty\");\n    }\n    if args.channel.trim().is_empty() {\n        bail!(\"--channel must not be empty\");\n    }\n    Ok(())\n}\n\nasync fn acquire_capture_ownership() -> Result<InstanceGuard> {\n    // The agent acquires this same lock before any HID I/O. An endpoint probe\n    // alone misses both early startup and a relaunch after the probe returns.\n    let guard = single_instance::acquire(\"agent.lock\").context(\n        \"refusing direct fixture capture: could not acquire agent.lock; \\\n         stop the OpenLogi agent and any other fixture capture before retrying\",\n    )?;\n    match tokio::time::timeout(AGENT_PROBE_TIMEOUT, client::connect()).await {\n        Ok(Err(ConnectError::Endpoint(error))) if endpoint_is_unreachable(&error) => Ok(guard),\n        Ok(Ok(_) | Err(ConnectError::Handshake(_) | ConnectError::Endpoint(_))) | Err(_) => bail!(\n            \"refusing direct fixture capture because the agent endpoint is active or accepted a \\\n             connection without completing a healthy handshake; this command uses the CLI's own \\\n             HID permission and identity, so stop the OpenLogi agent before retrying\"\n        ),","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/record_case.rs#L282-L318","documentation":"`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.","triggerScenarios":"Invoking `openlogi fixture record-case --channel \"\"` or `--channel \"  \"`, typically from a script where the channel variable is unset or blank.","commonSituations":"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.","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"],"exampleFix":"// before\nopenlogi fixture record-case --channel \"$CHANNEL\"   # CHANNEL blank\n// after\n: \"${CHANNEL:?CHANNEL must be set}\"\nopenlogi fixture record-case --channel \"$CHANNEL\"","handlingStrategy":"validation","validationCode":"if channel.trim().is_empty() {\n    return Err(\"--channel must be a non-empty channel identifier\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass an explicit --channel in scripts","Guard channel variables with ${CHANNEL:?msg}","Trim and validate inputs before building the command line"],"tags":["cli","validation","arguments","fixture"],"backgroundTag":"empty-required-field","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"}