{"record":{"id":"33ed296bfb0f1137","repo":"sinelaw/fresh","slug":"handshake-with-the-fresh-editor-failed","errorCode":null,"errorMessage":"handshake with the Fresh editor failed","messagePattern":"handshake with the Fresh editor failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":3672,"sourceCode":"    let conn = fresh::server::ipc::ClientConnection::connect(socket_paths).map_err(|e| {\n        if e.kind() == std::io::ErrorKind::PermissionDenied {\n            socket_denied_error(\n                &std::env::var(\"FRESH_SESSION\").unwrap_or_else(|_| \"?\".to_string()),\n                socket_paths,\n            )\n        } else {\n            anyhow::Error::from(e)\n        }\n    })?;\n    let mut reader = conn.control_reader();\n    let accepted = client_handshake_reading(&conn, || {\n        reader\n            .read_line_timeout(cmd_reply_timeout())\n            .map_err(cmd_read_error)\n    })?;\n    if !accepted {\n        // client_handshake already printed the mismatch reason.\n        anyhow::bail!(\"handshake with the Fresh editor failed\");\n    }\n    Ok(CmdConnection { conn, reader })\n}\n\n/// Read control replies until a `ScriptResult` arrives (or an error/EOF/timeout).\n/// Returns `(ok, error, output)`.\nfn read_script_result(\n    conn: &mut CmdConnection,\n    timeout: std::time::Duration,\n) -> AnyhowResult<(bool, Option<String>, Option<String>)> {\n    use fresh::server::protocol::ServerControl;\n    loop {\n        match conn.recv_within(timeout)? {\n            Some(ServerControl::ScriptResult { ok, error, output }) => {\n                return Ok((ok, error, output))\n            }\n            Some(ServerControl::Error { message }) => anyhow::bail!(\"server error: {}\", message),\n            Some(_) => continue,","sourceCodeStart":3654,"sourceCodeEnd":3690,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L3654-L3690","documentation":"After connecting to the editor's control socket, the client performs a protocol handshake via client_handshake. If the editor does not accept (protocol/version or capability mismatch), the client bails with this generic message; the specific mismatch reason was already printed by client_handshake to stderr.","triggerScenarios":"A fresh CLI client whose protocol version/capabilities differ from the running editor's, so the editor rejects the CmdConnection during handshake.","commonSituations":"Editor upgraded (or downgraded) while an old binary is still running and newer/older CLI invokes it; mixing two Fresh versions on PATH (e.g. one from cargo install, one distro package); connecting a stale CLI to a long-lived editor session.","solutions":["Read the mismatch reason printed just before this error on stderr.","Restart the editor so both sides run the same Fresh version.","Ensure the `fresh` on PATH is the same build as the running editor (`which fresh`, `fresh --version`).","Reinstall/upgrade so client and editor versions match."],"exampleFix":"# before\n~/.cargo/bin/fresh --cmd split right   # old client vs new editor\n# after\nhash -r; fresh --version && fresh --cmd split right   # same binary as running editor","handlingStrategy":"try-catch","validationCode":"// ensure client and editor versions match before connecting\nconst { execSync } = require('child_process');\nconst cliV = execSync('fresh --version').toString().trim();\nconst srvV = execSync('fresh --cmd version').toString().trim();\nif (cliV !== srvV) { console.error(`version mismatch: cli=${cliV} editor=${srvV}; restart editor`); process.exit(1); }","typeGuard":null,"tryCatchPattern":"// rust\nmatch connect_and_handshake(&paths) {\n    Ok(conn) => conn,\n    Err(e) if e.to_string().contains(\"handshake\") => {\n        eprintln!(\"version mismatch with running editor; restart it and retry\");\n        std::process::exit(2);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep one fresh binary on PATH; avoid mixing cargo-install and distro builds.","Restart the editor after upgrading Fresh.","Pin the editor and CLI to the same version in scripts.","Read the mismatch details printed before this generic error."],"tags":["cli","ipc","handshake","version-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}