Hmbown/CodeWhale · error · anyhow::Error
Antigravity cloud-code SSE is not JSON
Error message
Antigravity cloud-code SSE is not JSON: {err} What it means
Each cloud-code SSE data frame that is not the [DONE] sentinel is parsed with serde_json::from_str. If the frame is not valid JSON, the adapter yields 'Antigravity cloud-code SSE is not JSON' with the serde error and terminates the stream - it does not skip the frame or attempt recovery.
Solutions
- Replay the same request with curl -N to see the actual frame content.
- If it is an auth or HTML page, fix credentials or the endpoint URL before retrying.
- Remove proxy injections (block pages, banners) on the cloud-code route.
- If frames are genuinely JSON but interleaved with text, report upstream - the adapter fails closed on the first non-JSON frame.
Defensive patterns
Strategy: validation
Validate before calling
// Rust: probe that cloud-code data frames are JSON before wiring the consumer
let first = first_data_frame(&mut resp).await?; // "data: {...}"
let payload = extract_sse_data_value(&first).context("no data frame")?;
serde_json::from_str::<serde_json::Value>(payload)
.context("cloud-code route returned non-JSON (auth page?)")?;
Try / catch
// deterministic - fix credentials/endpoint instead of retrying
Err(err) if err.to_string().contains("SSE is not JSON") => {
return Err(err.context("verify cloud-code credentials and base URL"));
}
Prevention
- Confirm cloud-code credentials are valid before long sessions - HTML auth pages are the usual non-JSON payload.
- Keep proxy block pages and banners off the SSE route.
- Pin the base URL to the documented cloud-code endpoint.
When it happens
Trigger: The gateway answers the SSE route with an HTML login/error page or plain-text message; a proxy error or block page injected mid-stream; a data frame containing non-JSON text (banner, logging preamble); partial frame corruption.
Common situations: Expired or missing Antigravity credentials returning an HTML auth redirect; a wrong base URL; corporate proxies injecting block pages; environment banners prepended to streams.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- Antigravity cloud-code HTTP
- Antigravity cloud-code SSE shape is unproven; failing closed
- {err}
- SSE stream idle timeout after
- Stream read error
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/ee0094e98cb63709.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client/cloud_code.rs:218
Ok(None) => break,
Err(err) => {
yield Err(anyhow::anyhow!("{err}"));
return;
}
};
if line.is_empty() || line.starts_with(':') {
continue;
}
let Some(data) = super::extract_sse_data_value(&line) else {
continue;
};
if data == "[DONE]" {
break;
}
let value: Value = match serde_json::from_str(data) {
Ok(value) => value,
Err(err) => {
yield Err(anyhow::anyhow!(
"Antigravity cloud-code SSE is not JSON: {err}"
));
return;
}
};
if let Some(error) = value.get("error") {
yield Ok(StreamEvent::Error {
error: error.clone(),
});
return;
}
let Some(text) = extract_cloud_code_text(&value) else {
if value.get("response").is_some() || value.get("candidates").is_some() {
continue;
}
yield Err(anyhow::anyhow!(
"Antigravity cloud-code SSE shape is unproven; failing closed"
));View on GitHub (pinned to 0c42157ee5)