xai-org/grok-build · error

--prompt-json: {e}

Error message

--prompt-json: {e}

What it means

PromptSource::from_args wraps failures of Self::from_json(json_str) as '--prompt-json: {e}'. The --prompt-json flag value must parse as the expected prompt content-blocks JSON; invalid JSON or a structure that does not match the content-block schema produces this error.

Source

Thrown at crates/codegen/xai-grok-pager/src/headless/cli.rs:50

    Text(String),
    Blocks(Vec<acp::ContentBlock>),
}

impl HeadlessPrompt {
    /// Build from mutually-exclusive CLI prompt args. `None` means interactive mode.
    pub fn from_args(
        single: Option<&str>,
        prompt_json: Option<&str>,
        prompt_file: Option<&Path>,
    ) -> anyhow::Result<Option<Self>> {
        if let Some(text) = single {
            Self::from_text(text)
                .map(Some)
                .map_err(|e| anyhow::anyhow!("--single: {e}"))
        } else if let Some(json_str) = prompt_json {
            Self::from_json(json_str)
                .map(Some)
                .map_err(|e| anyhow::anyhow!("--prompt-json: {e}"))
        } else if let Some(path) = prompt_file {
            Self::from_file(path).map(Some)
        } else {
            Ok(None)
        }
    }

    /// `.json` files are parsed as content blocks, everything else as text.
    pub fn from_file(path: &Path) -> anyhow::Result<Self> {
        let content = std::fs::read_to_string(path)
            .map_err(|e| anyhow::anyhow!("Failed to read '{}': {e}", path.display()))?;

        let context = |e| anyhow::anyhow!("'{}': {e}", path.display());
        if path.extension().and_then(|e| e.to_str()) == Some("json") {
            Self::from_json(&content).map_err(context)
        } else {
            Self::from_text(&content).map_err(context)
        }

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Validate the JSON structure against the content-block schema before passing
  2. Pipe through jq '.' to catch syntax errors early
  3. Use --prompt-file with a .json file instead of an inline flag
  4. Check the inner {e} for the exact deserialization field mismatch

Example fix

// before
--prompt-json '[{"type": "text"}]'
// after
--prompt-json '[{"type": "text", "text": "hello"}]'
Defensive patterns

Strategy: validation

Validate before calling

fn validate_prompt_json(s: &str) -> Result<(), String> {
    let v: serde_json::Value = serde_json::from_str(s)
        .map_err(|e| format!("invalid JSON: {e}"))?;
    let blocks = v.as_array().ok_or("expected array of content blocks")?;
    for b in blocks {
        if b.get("type").and_then(|t| t.as_str()).is_none() {
            return Err("block missing 'type'".into());
        }
    }
    Ok(())
}

Type guard

fn is_content_block_array(s: &str) -> bool {
    serde_json::from_str::<serde_json::Value>(s).ok()
        .and_then(|v| v.as_array().map(|a| {
            !a.is_empty() && a.iter().all(|b| b.get("type").and_then(|t| t.as_str()).is_some())
        }))
        .unwrap_or(false)
}

Try / catch

match PromptSource::from_args(None, prompt_json.as_deref(), None) {
    Ok(Some(src)) => src,
    Ok(None) => { eprintln!("no prompt given"); std::process::exit(2); }
    Err(e) => { eprintln!("{e:#}"); std::process::exit(2); }
}

Prevention

When it happens

Trigger: Passing --prompt-json with malformed JSON, or JSON whose shape is not valid prompt content blocks (wrong array/object shape, unknown block types, missing required fields).

Common situations: Hand-writing content-block JSON with syntax errors; copying block format from a different API version; jq/yq output piped with quoting issues.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/d06e869e15706051. Report an issue: GitHub.