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
- Validate the JSON structure against the content-block schema before passing
- Pipe through jq '.' to catch syntax errors early
- Use --prompt-file with a .json file instead of an inline flag
- 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
- Validate content-block JSON against the schema before passing
- Generate blocks with a typed builder, not string concatenation
- Pipe through jq '.' to catch syntax errors
- Pin the content-block schema version used by your tooling
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
- Failed to load manifest: {e}
- --json-schema: invalid JSON: {e}
- --single: {e}
- Failed to read '{path}': {e}
- '{path}': {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/d06e869e15706051.
Report an issue: GitHub.