{"record":{"id":"791b78fa21bf0f5b","repo":"sinelaw/fresh","slug":"unexpected-server-response","errorCode":null,"errorMessage":"Unexpected server response","messagePattern":"Unexpected server response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":3370,"sourceCode":"        .ok_or_else(|| anyhow::anyhow!(\"Server closed connection during handshake\"))?;\n\n    match serde_json::from_str::<ServerControl>(&response)? {\n        ServerControl::Hello(server_hello) => {\n            if server_hello.protocol_version != PROTOCOL_VERSION {\n                eprintln!(\n                    \"Version mismatch: server is v{}\",\n                    server_hello.server_version\n                );\n                return Ok(false);\n            }\n            Ok(true)\n        }\n        ServerControl::VersionMismatch(mismatch) => {\n            eprintln!(\"Version mismatch: server is v{}\", mismatch.server_version);\n            Ok(false)\n        }\n        ServerControl::Error { message } => Err(anyhow::anyhow!(\"Server error: {}\", message)),\n        _ => Err(anyhow::anyhow!(\"Unexpected server response\")),\n    }\n}\n\n/// When launched from inside Fresh's own embedded terminal, forward the\n/// file/dir arguments to the parent editor (identified by `FRESH_SESSION`)\n/// instead of starting a second editor in the terminal.\n///\n/// Returns:\n/// - `Some(Ok(()))` — forwarded; the caller should exit.\n/// - `None` — not a nested launch, nothing to forward, or the parent\n///   socket is unreachable; the caller should launch inline as usual.\nfn try_forward_nested(args: &Args) -> Option<AnyhowResult<()>> {\n    // Only plain interactive file/dir opens are forwarded. Subcommands,\n    // --server and --attach are already handled before we get here;\n    // --stdin pipes content into a real editor and can't be forwarded.\n    if args.server || args.attach || args.stdin || args.files.is_empty() {\n        return None;\n    }","sourceCodeStart":3352,"sourceCodeEnd":3388,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L3352-L3388","documentation":"The catch-all arm of the handshake response match in main.rs. After sending Hello, the CLI expects `Hello`, `VersionMismatch`, or `Error`; any other `ServerControl` variant reaches `_` and becomes this error. It signals that the peer speaks an unrecognized or corrupted message set rather than a known failure.","triggerScenarios":"The server's first control message deserializes into a valid `ServerControl` but is none of Hello/VersionMismatch/Error — e.g. a newer protocol with extra variants, or a reply meant for a different request type.","commonSituations":"Client and server built from different commits so new variants exist on one side; a proxy or shim injecting unexpected control frames; a bug where the server skips the Hello reply.","solutions":["Check that client CLI and editor versions match (same PROTOCOL_VERSION / same build).","Log the raw response string before parsing to see which variant actually arrived.","Update both client and editor to the latest release so the ServerControl enum is identical.","If a middle process sits on the socket, remove it and connect directly to the editor."],"exampleFix":"// before\n_ => Err(anyhow::anyhow!(\"Unexpected server response\")),\n// after: preserve the offending payload for diagnosis\n_ => Err(anyhow::anyhow!(\"Unexpected server response: {}\", response)),","handlingStrategy":"validation","validationCode":"const KNOWN: [&str;3] = [\"Hello\",\"VersionMismatch\",\"Error\"];\nfn is_known_handshake_variant(raw: &str) -> bool {\n    KNOWN.iter().any(|k| raw.trim_start_matches('{').contains(k))\n}","typeGuard":"fn is_handshake_response(msg: &ServerControl) -> bool {\n    matches!(msg, ServerControl::Hello(_) | ServerControl::VersionMismatch(_) | ServerControl::Error { .. })\n}","tryCatchPattern":"if let Err(e) = handshake() {\n    if e.to_string().starts_with(\"Unexpected server response\") {\n        eprintln!(\"protocol mismatch — verify client/server versions; raw: {raw}\");\n    }\n}","preventionTips":["Match PROTOCOL_VERSION between client and editor","Log raw control frames before parsing to diagnose variant drift","Upgrade both binaries together","Never put non-handshake services on the editor's control socket"],"tags":["ipc","handshake","protocol","cli"],"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"}