{"record":{"id":"4b1adc679e8fb4d3","repo":"xai-org/grok-build","slug":"json-schema-invalid-json-e","errorCode":null,"errorMessage":"--json-schema: invalid JSON: {e}","messagePattern":"--json-schema: invalid JSON: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/headless/cli.rs","lineNumber":23,"sourceCode":"use agent_client_protocol as acp;\nuse clap::ValueEnum;\n\n#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, ValueEnum)]\npub enum OutputFormat {\n    #[default]\n    Plain,\n    Json,\n    /// NDJSON: one ACP session update per line, the agent's native format.\n    #[value(name = \"streaming-json\")]\n    StreamingJson,\n    /// NDJSON in the Anthropic Messages API wire format.\n    #[value(name = \"streaming-messages-json\")]\n    StreamingMessagesJson,\n}\n\npub fn parse_json_schema(input: &str) -> anyhow::Result<serde_json::Value> {\n    let schema: serde_json::Value = serde_json::from_str(input)\n        .map_err(|e| anyhow::anyhow!(\"--json-schema: invalid JSON: {e}\"))?;\n    if !schema.is_object() {\n        anyhow::bail!(\"--json-schema: must be a JSON object describing a JSON Schema\");\n    }\n    Ok(schema)\n}\n\n#[derive(Debug, Clone)]\npub enum HeadlessPrompt {\n    Text(String),\n    Blocks(Vec<acp::ContentBlock>),\n}\n\nimpl HeadlessPrompt {\n    /// Build from mutually-exclusive CLI prompt args. `None` means interactive mode.\n    pub fn from_args(\n        single: Option<&str>,\n        prompt_json: Option<&str>,\n        prompt_file: Option<&Path>,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/headless/cli.rs#L5-L41","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\n--json-schema '{\"type\": \"object\", properties: {}}'\n// after\n--json-schema '{\"type\": \"object\", \"properties\": {}}'","handlingStrategy":"validation","validationCode":"fn validate_schema_arg(input: &str) -> Result<(), String> {\n    let v: serde_json::Value = serde_json::from_str(input)\n        .map_err(|e| format!(\"--json-schema: invalid JSON: {e}\"))?;\n    if !v.is_object() { return Err(\"--json-schema: must be a JSON object\".into()); }\n    Ok(())\n}","typeGuard":"fn is_json_object(s: &str) -> bool {\n    serde_json::from_str::<serde_json::Value>(s)\n        .map(|v| v.is_object())\n        .unwrap_or(false)\n}","tryCatchPattern":"match parse_json_schema(raw) {\n    Ok(schema) => schema,\n    Err(e) => { eprintln!(\"{e:#}\"); std::process::exit(2); }\n}","preventionTips":["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)"],"tags":["cli","json","validation","structured-output"],"backgroundTag":"invalid-json-input","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}