AprilNEA/OpenLogi · error
the running Agent speaks protocol v
Error message
the running Agent speaks protocol v{}, but this CLI requires v{PROTOCOL_VERSION}; update or restart OpenLogi so both processes match (no profile was written) What it means
After connecting, `capture_connected_profile` compares the agent's negotiated wire-protocol version against the CLI's `PROTOCOL_VERSION`. The IPC wire format is append-only and versioned; when the versions differ the CLI aborts before reading a profile so no partial or misinterpreted data is written. This error means the running agent and the CLI were built from mismatched versions of the codebase.
Solutions
- Quit/restart the running OpenLogi agent so it matches the CLI's build (restart the OpenLogi app or kill openlogi-agent and relaunch)
- Update or reinstall OpenLogi so both binaries come from the same release
- Rebuild both `openlogi-cli` and `openlogi-agent` from the same commit if developing
- If a stale agent keeps relaunching, kill it and wait for the LaunchServices-launched replacement or start the GUI to relaunch it
Example fix
// before: agent from v1 bundle, CLI from v2 source connection.version = 1, PROTOCOL_VERSION = 2 -> bail! // after $ pkill openlogi-agent && open /Applications/OpenLogi.app # relaunch matching agent // wire check passes: connection.version == PROTOCOL_VERSION
Defensive patterns
Strategy: validation
Validate before calling
// before capture, surface the mismatch clearly
if connection.version != PROTOCOL_VERSION {
eprintln!("agent protocol v{}, CLI needs v{} — restart OpenLogi", connection.version, PROTOCOL_VERSION);
} Try / catch
if let Err(e) = run().await {
if e.to_string().contains("speaks protocol v") && e.to_string().contains("requires v") {
eprintln!("Version mismatch: restart the agent so it matches this CLI, then rerun.");
}
} Prevention
- After every rebuild or update, restart both the agent and CLI from the same build
- Kill stale openlogi-agent processes after pulling new code; remember the agent self-restarts ~20s after a dev run
- Never mix a production bundle agent with a dev-built CLI
- Bump/check PROTOCOL_VERSION and openlogi-ipc wire_format tests together when touching wire types
When it happens
Trigger: Calling `record_profile` (via `capture_for_contribution`/`capture_connected`) against a running agent whose `connection.version` differs from the CLI's `PROTOCOL_VERSION` — typically an old agent still running after a rebuild or upgrade.
Common situations: Updating OpenLogi (bumping PROTOCOL_VERSION) while the old agent process is still alive (~20s self-restart window after a dev run); a dev-built CLI talking to a production agent or vice versa; a partial update where one binary was replaced but not the other.
Related errors
- could not reach the running OpenLogi Agent; start the Agent…
- the running OpenLogi Agent did not complete a healthy IPC…
- the running Agent timed out before semantic capture could…
- the running Agent disconnected before semantic capture…
- the running Agent timed out while providing its device…
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/cca784ab2f758395.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/record_profile.rs:128
"Recorded semantic profile `{}` to {} through the running Agent.",
profile.id,
args.output.display()
);
println!(
"The captured values are semantic review candidates, not proof of physical or protocol \
correctness. Review the profile before committing it."
);
Ok(())
}
async fn capture_connected_profile(
connection: &Connection,
selector: Option<&str>,
id: String,
name: String,
) -> Result<CapturedProfile> {
if connection.version != PROTOCOL_VERSION {
bail!(
"the running Agent speaks protocol v{}, but this CLI requires v{PROTOCOL_VERSION}; \
update or restart OpenLogi so both processes match (no profile was written)",
connection.version
);
}
tokio::time::timeout(
DECLARE_TIMEOUT,
connection
.client
.declare_client(context::current(), ClientKind::Cli),
)
.await
.map_err(|_| anyhow!("the running Agent timed out before semantic capture could begin"))?
.map_err(|_| anyhow!("the running Agent disconnected before semantic capture could begin"))?;
let snapshot = tokio::time::timeout(
SNAPSHOT_TIMEOUT,View on GitHub (pinned to e846e6f4b4)