jlcodes99/cockpit-tools · warning
[WakeupGateway] 官方 LS LanguageServerStarted 解析失败: {}
Error message
[WakeupGateway] 官方 LS LanguageServerStarted 解析失败: {} What it means
The gateway module implements a local mock of the official LS's Connect RPC surface. When an incoming POST matches the LanguageServerStarted RPC method, route_official_ls_extension_request calls parse_official_ls_started_request on the request body; if protobuf parsing fails it logs '官方 LS LanguageServerStarted 解析失败: {}' and returns HTTP 400 Bad Request with the parse error. This happens because the incoming Connect/proto envelope did not decode into the expected LanguageServerStarted message.
Source
Thrown at src-tauri/src/modules/wakeup_gateway.rs:1252
"text/plain; charset=utf-8",
));
}
if path_matches_rpc_method(&path, "LanguageServerStarted") {
match parse_official_ls_started_request(&parsed.body) {
Ok(started) => {
if let Ok(mut guard) = state.started_sender.lock() {
if let Some(tx) = guard.take() {
let _ = tx.send(started);
}
}
return OfficialLsExtensionAction::Close(extension_unary_response(
&content_type,
&[],
));
}
Err(err) => {
crate::modules::logger::log_error(&format!(
"[WakeupGateway] 官方 LS LanguageServerStarted 解析失败: {}",
err
));
return OfficialLsExtensionAction::Close(text_response(
400,
"Bad Request",
&err,
"text/plain; charset=utf-8",
));
}
}
}
if path_matches_rpc_method(&path, "SubscribeToUnifiedStateSyncTopic") {
let topic = match parse_subscribe_topic_from_connect_body(&parsed.body) {
Ok(v) => v,
Err(err) => {
crate::modules::logger::log_error(&format!(View on GitHub (pinned to 1ed8b77992)
Solutions
- Log and inspect the raw request bytes and content-type header alongside the parse error to confirm whether the body is protobuf at all.
- Update parse_official_ls_started_request to match the proto schema of the installed official LS version (compare against the LS's bundled .proto definitions).
- Reject unsupported content-types early with a clear 415-style response instead of attempting protobuf decode on JSON or form bodies.
- Verify the Connect envelope framing: for application/connect+proto the body is length-prefixed messages; strip the envelope before decoding the inner message.
- Capture the offending payload (bounded hex/log dump) for a bug report if the sender is a legitimate LS build.
Example fix
// before: parse regardless of content-type
match parse_official_ls_started_request(&parsed.body) { ... }
// after: guard content-type and log offending bytes on failure
if !content_type.contains("proto") {
return Close(text_response(415, "Unsupported Media Type", "expected application/proto", "text/plain; charset=utf-8"));
}
match parse_official_ls_started_request(&parsed.body) {
Ok(started) => ...,
Err(err) => {
log_error(&format!("LanguageServerStarted 解析失败: {} (len={}, head={:?})", err, parsed.body.len(), &parsed.body[..parsed.body.len().min(32)]));
Close(text_response(400, "Bad Request", &err, "text/plain; charset=utf-8"))
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate before parsing: content-type and non-empty protobuf-ish body
fn plausibly_proto(body: &[u8], content_type: &str) -> bool {
content_type.to_ascii_lowercase().contains("proto") && !body.is_empty()
} Try / catch
// Server-side: never panic on bad input; respond 400 and keep serving
match parse_official_ls_started_request(&parsed.body) {
Ok(started) => { /* forward to started_sender */ }
Err(err) => {
log_error(&format!("LanguageServerStarted 解析失败: {}", err));
return OfficialLsExtensionAction::Close(text_response(400, "Bad Request", &err, "text/plain; charset=utf-8"));
}
} Prevention
- Check the content-type header before protobuf decode and reject JSON/plain bodies with 415.
- Keep the proto parser in sync with the official LS version; add a unit test per supported LS version.
- Log a bounded hex dump of bodies that fail to parse so upgrades that change the schema are diagnosable.
- Firewall the local extension port to loopback-only clients to avoid garbage traffic.
When it happens
Trigger: An official LS (or any client) POSTs to the local extension server's LanguageServerStarted endpoint and parse_official_ls_started_request returns Err: malformed or truncated protobuf body, wrong Connect envelope framing (unary vs streaming content-type), empty body, or a proto schema version whose field layout no longer matches the parser.
Common situations: Official LS version upgrade changed the LanguageServerStarted proto definition; a client sends application/json where application/proto is expected (or vice versa) so the bytes are not valid protobuf; proxy or middleware corrupts/truncates the request body; a security scanner or wrong client hits the local port with garbage bytes.
Related errors
- [WakeupGateway] 官方 LS SubscribeToUnifiedStateSyncTopic 解析失败:
- 官方 LS 返回错误: {} - {} ({})
- invalidJsonMessage
- messages.invalidJson
- errorCode (parseJsonOrThrow caller-supplied)
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/51648ac44da122c7.
Report an issue: GitHub.