xai-org/grok-build · error
--json-schema: invalid JSON: {e}
Error message
--json-schema: invalid JSON: {e} What it means
parse_json_schema parses the --json-schema flag value with serde_json::from_str and wraps parse failures as '--json-schema: invalid JSON: {e}'. A following check also rejects non-object schemas. It exists so malformed structured-output schemas fail fast at argument parsing.
Source
Thrown at crates/codegen/xai-grok-pager/src/headless/cli.rs:23
use agent_client_protocol as acp;
use clap::ValueEnum;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, ValueEnum)]
pub enum OutputFormat {
#[default]
Plain,
Json,
/// NDJSON: one ACP session update per line, the agent's native format.
#[value(name = "streaming-json")]
StreamingJson,
/// NDJSON in the Anthropic Messages API wire format.
#[value(name = "streaming-messages-json")]
StreamingMessagesJson,
}
pub fn parse_json_schema(input: &str) -> anyhow::Result<serde_json::Value> {
let schema: serde_json::Value = serde_json::from_str(input)
.map_err(|e| anyhow::anyhow!("--json-schema: invalid JSON: {e}"))?;
if !schema.is_object() {
anyhow::bail!("--json-schema: must be a JSON object describing a JSON Schema");
}
Ok(schema)
}
#[derive(Debug, Clone)]
pub enum HeadlessPrompt {
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>,View on GitHub (pinned to bc7f02eddd)
Solutions
- Validate the JSON with jq/python before passing it
- Use single-quoted heredocs or --@file-style input to avoid shell mangling
- Ensure the top level is a JSON object
- Prefer reading the schema from a file rather than an inline flag
Example fix
// before
--json-schema '{"type": "object", properties: {}}'
// after
--json-schema '{"type": "object", "properties": {}}' Defensive patterns
Strategy: validation
Validate before calling
fn validate_schema_arg(input: &str) -> Result<(), String> {
let v: serde_json::Value = serde_json::from_str(input)
.map_err(|e| format!("--json-schema: invalid JSON: {e}"))?;
if !v.is_object() { return Err("--json-schema: must be a JSON object".into()); }
Ok(())
} Type guard
fn is_json_object(s: &str) -> bool {
serde_json::from_str::<serde_json::Value>(s)
.map(|v| v.is_object())
.unwrap_or(false)
} Try / catch
match parse_json_schema(raw) {
Ok(schema) => schema,
Err(e) => { eprintln!("{e:#}"); std::process::exit(2); }
} Prevention
- Validate schema JSON with jq before invoking
- Read schemas from files instead of inline shell args
- Use single quotes to prevent shell interpolation
- Lint the JSON Schema itself (types, required fields)
When it happens
Trigger: Passing --json-schema with malformed JSON (trailing commas, single quotes, unquoted keys) or with a valid JSON value that is not an object (e.g. a bare string or array).
Common situations: Building the flag with shell quoting that mangles the JSON; generating the schema with string concatenation; YAML or JS-object-literal syntax pasted in instead of strict JSON.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Error: --session-id must be a valid UUID (got '{session_id}'
- {CHAT_MODE_FORK_CONFLICT}
- --header can only be used with HTTP or SSE servers.
- A URL is required for {label} servers. Usage: grok mcp add -
- Invalid URL '{url}'. Server URLs must start with http:// or
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/4b1adc679e8fb4d3.
Report an issue: GitHub.