jlcodes99/cockpit-tools · error
官方 LS 返回错误: {} - {} ({})
Error message
官方 LS 返回错误: {} - {} ({}) What it means
post_json_to_official_ls POSTs JSON to the official local Language Server (127.0.0.1 HTTPS with self-signed cert, CSRF header x-codeium-csrf-token). Any non-2xx HTTP status is converted into Err(format!("官方 LS 返回错误: {} - {} ({})", status, text, path)) after logging a 512-char body preview. The message embeds the HTTP status code, the raw response body, and the request path so the caller can see exactly which LS RPC failed and why.
Source
Thrown at src-tauri/src/modules/wakeup_gateway.rs:1121
.header("x-codeium-csrf-token", csrf_token)
.json(body)
.send()
.await
.map_err(|e| format!("官方 LS 请求失败: {} ({})", e, path))?;
if !resp.status().is_success() {
let status = resp.status();
let text = resp.text().await.unwrap_or_default();
let preview: String = text.chars().take(512).collect();
crate::modules::logger::log_error(&format!(
"[WakeupGateway] 官方 LS 返回错误: status={}, path={}, body_len={}, body={}",
status,
path,
text.len(),
preview
));
return Err(format!(
"官方 LS 返回错误: {} - {} ({})",
status, text, path
));
}
resp.json::<Value>()
.await
.map_err(|e| format!("官方 LS 响应解析失败: {} ({})", e, path))
}
enum OfficialLsExtensionAction {
Close(Vec<u8>),
HoldStream {
content_type: String,
first_message: Vec<u8>,
shutdown_notify: Arc<Notify>,
},
}
View on GitHub (pinned to 1ed8b77992)
Solutions
- Read the status and path in the message: 401/403 means re-fetch the CSRF token (and re-auth) from the current LS instance and retry.
- 400 with a body usually indicates request schema mismatch — compare the body against the LS version's expected schema and fix or drop the field.
- 404 means the path does not exist in this LS build — check the LS version and update the RPC path or gate the call on a version check.
- 500/502 points at the LS itself: check the LS process logs, restart it, and add a bounded retry with backoff for transient 5xx.
- Log the full body (already previewed to 512 chars) when filing an issue; the body usually contains the LS's own error JSON explaining the rejection.
Example fix
// before: single attempt, raw error surfaces
let v = post_json_to_official_ls(&client, &base, &csrf, path, &body).await?;
// after: refresh CSRF + bounded retry on auth failure
match post_json_to_official_ls(&client, &base, &csrf, path, &body).await {
Err(e) if e.contains(" 401 ") || e.contains(" 403 ") => {
let csrf = refresh_csrf_token(&base).await?;
post_json_to_official_ls(&client, &base, &csrf, path, &body).await
}
other => other,
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: token present and LS reachable before the RPC
if csrf_token.is_empty() {
return Err("missing x-codeium-csrf-token; refresh token first".into());
}
let ok = client.get(format!("{}", base_url.trim_end_matches('/')))
.timeout(Duration::from_secs(3)).send().await
.map(|r| r.status().is_success()).unwrap_or(false);
if !ok { return Err("official LS not reachable".into()); } Try / catch
match post_json_to_official_ls(&client, &base, &csrf, path, &body).await {
Err(e) => {
// e = "官方 LS 返回错误: <status> - <body> (<path>)"
if e.starts_with("官方 LS 返回错误: 401") || e.starts_with("官方 LS 返回错误: 403") {
let fresh = refresh_csrf_token(&base).await?;
return post_json_to_official_ls(&client, &base, &fresh, path, &body).await;
}
if e.starts_with("官方 LS 返回错误: 5") { /* bounded retry with backoff */ }
Err(e)
}
ok => ok,
} Prevention
- Always send the current x-codeium-csrf-token; refresh it after any LS restart instead of caching across sessions.
- Pin/gate calls on the official LS version and check that the RPC path still exists before invoking it.
- Keep request JSON schemas in one module per LS RPC so version drift is caught by tests, not 400s in production.
- Add bounded exponential-backoff retries for 5xx only; never blind-retry 4xx.
When it happens
Trigger: Any post_json_to_official_ls call where the official LS responds with a non-success HTTP status: 400 on malformed request body, 401/403 on missing/invalid x-codeium-csrf-token or expired auth, 404 when the LS build does not expose the requested RPC path, 5xx on internal LS failure.
Common situations: Stale CSRF token after LS restart while the caller caches the old token; calling an RPC path that was renamed or removed in a newer/older official LS binary; LS overloaded or crashed mid-request returning 500; request JSON schema drift after an LS version change causing 400 Bad Request.
Related errors
- [TraeAutoCheckin] 账号 ${account.id} 签到异常:
- Token 刷新失败: status={}
- [WS] 接收错误 {}: {}
- 网关未在超时时间内返回唤醒结果,最后状态={}
- [WakeupGateway] 官方 LS LanguageServerStarted 解析失败: {}
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/9aff8405842e6ef9.
Report an issue: GitHub.