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

  1. 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.
  2. 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.
  3. 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.
  4. 500/502 points at the LS itself: check the LS process logs, restart it, and add a bounded retry with backoff for transient 5xx.
  5. 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

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


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/9aff8405842e6ef9. Report an issue: GitHub.