Hmbown/CodeWhale · error · anyhow::Error

Antigravity cloud-code request has no text contents

Error message

Antigravity cloud-code request has no text contents

What it means

After iterating all messages and skipping empty/whitespace text blocks, the builder found zero `contents` entries to send and bails. This means every message either had no text blocks or only blank ones (non-text blocks would have failed earlier with the content-type error). Sending an empty conversation to cloud-code has no meaning, so the request is refused locally.

Source

Thrown at crates/tui/src/client/cloud_code.rs:85

        };
        let mut parts = Vec::new();
        for block in &message.content {
            match block {
                ContentBlock::Text { text, .. } if !text.trim().is_empty() => {
                    parts.push(json!({ "text": text }));
                }
                ContentBlock::Text { .. } => {}
                _ => bail!(
                    "Antigravity cloud-code accepts text parts only; non-text content fails closed"
                ),
            }
        }
        if !parts.is_empty() {
            contents.push(json!({ "role": role, "parts": parts }));
        }
    }
    if contents.is_empty() {
        bail!("Antigravity cloud-code request has no text contents");
    }
    let model = request.model.trim();
    if model.is_empty() {
        bail!("Antigravity cloud-code request is missing a model id");
    }
    Ok(json!({
        "model": model,
        "userAgent": "codewhale",
        "request": {
            "contents": contents,
        }
    }))
}

/// Pull visible text out of a cloud-code SSE JSON object. Unknown shapes
/// return `None` so the caller can fail closed instead of guessing.
pub fn extract_cloud_code_text(value: &Value) -> Option<String> {
    if let Some(text) = value.pointer("/response/candidates/0/content/parts/0/text") {

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Ensure at least one message contains non-whitespace text before submitting
  2. Validate the prompt client-side and refuse empty submissions
  3. Check any history-trimming/redaction step that may blank out message text in place

Example fix

// before
let text = "   "; // whitespace-only -> contents empty -> bail

// after
let text = text.trim();
anyhow::ensure!(!text.is_empty(), "prompt must contain non-empty text");
Defensive patterns

Strategy: validation

Validate before calling

let has_text = request.messages.iter().any(|m| {
    m.content.iter().any(|b| matches!(b, ContentBlock::Text { text, .. } if !text.trim().is_empty()))
});
anyhow::ensure!(has_text, "refusing to send a request with no text contents");

Type guard

fn has_nonempty_text(messages: &[ChatMessage]) -> bool {
    messages.iter().any(|m| {
        m.content.iter().any(|b| matches!(b, ContentBlock::Text { text, .. } if !text.trim().is_empty()))
    })
}

Try / catch

if !has_nonempty_text(&request.messages) {
    return Ok(None); // nothing to say; skip the turn entirely
}
match client.create_message_stream(request).await { /* ... */ }

Prevention

When it happens

Trigger: A request where every message's text is empty or whitespace-only, e.g. a user turn of " ", or a message list composed solely of blank assistant messages.

Common situations: A UI that allows submitting an empty prompt; upstream trimming logic that empties messages (e.g. redaction) without dropping them; automated pipelines sending placeholder turns.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/163bbf036aab95b9. Report an issue: GitHub.