AprilNEA/OpenLogi · error

refusing direct fixture capture because the agent endpoint…

Error message

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

What it means

`acquire_capture_ownership` takes the agent's `agent.lock` and then probes the agent's IPC endpoint. Direct fixture capture uses the CLI's own HID permission and identity, which would conflict with a running agent, so any reachable endpoint — or one that accepts a connection but fails a healthy handshake — causes this refusal.

Solutions

  1. Stop the OpenLogi agent (quit it from the GUI or kill the openlogi-agent process), wait a moment so it does not self-relaunch, then retry
  2. Remove any stale lock/socket state left by a crashed agent, then retry
  3. If the agent keeps relaunching, disable autostart temporarily (e.g. OPENLOGI_DEV_AGENT=0 for dev runs) before recording
  4. Use the mock/dev workflow instead of direct capture if you need the agent running concurrently

Example fix

// before
openlogi fixture record-case ...   # agent still running
// after
pkill openlogi-agent   # and quit the GUI so it doesn't relaunch
openlogi fixture record-case ...
Defensive patterns

Strategy: validation

Validate before calling

// stop the agent, then confirm the socket is gone before recording
pkill -x openlogi-agent || true
if [ -S "$(openlogi agent-socket-path 2>/dev/null)" ]; then echo "agent socket still live"; exit 1; fi

Try / catch

if err.to_string().contains("agent endpoint is active") {
    eprintln!("stop the OpenLogi agent, then retry the record command");
}

Prevention

When it happens

Trigger: Running `openlogi fixture record-case` while the OpenLogi agent is running and its IPC socket is live; a stale agent process holding agent.lock with an accepting (but wedged) socket; an endpoint that accepts connections but fails the tarpc handshake within AGENT_PROBE_TIMEOUT.

Common situations: GUI-launched agent still running in the background (it self-relaunches ~20s later if left alive); a leftover agent from a crashed dev run; macOS LaunchServices-launched agent started by a previous `cargo run -p openlogi-desktop`.

Understand the failure class

Related errors


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

Appendix: source

Thrown at crates/openlogi-cli/src/cmd/fixture/record_case.rs:314

    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"
        ),
    }
}

fn endpoint_is_unreachable(error: &io::Error) -> bool {
    matches!(
        error.kind(),
        io::ErrorKind::NotFound | io::ErrorKind::ConnectionRefused
    )
}

fn online_targets(inventories: &[DeviceInventory]) -> Vec<TargetCandidate> {
    inventories
        .iter()
        .flat_map(|inventory| {

View on GitHub (pinned to e846e6f4b4)