{"record":{"id":"c70e1a6626655669","repo":"cube-js/cube","slug":"data-must-be-a-json-object","errorCode":null,"errorMessage":"--data must be a JSON object","messagePattern":"--data must be a JSON object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust/cube-cli/src/util.rs","lineNumber":28,"sourceCode":"/// Accepts inline JSON (`'{\"name\": \"x\"}'`), `@path/to/file.json`, or `-`\n/// to read from stdin — the same convention as `gh api` / `curl -d`.\npub fn parse_data(data: Option<&str>) -> Result<Map<String, Value>> {\n    let Some(data) = data else {\n        return Ok(Map::new());\n    };\n    let raw = if data == \"-\" {\n        let mut buf = String::new();\n        std::io::stdin().read_to_string(&mut buf)?;\n        buf\n    } else if let Some(path) = data.strip_prefix('@') {\n        std::fs::read_to_string(path).with_context(|| format!(\"failed to read {path}\"))?\n    } else {\n        data.to_string()\n    };\n    let value: Value = serde_json::from_str(&raw).context(\"--data is not valid JSON\")?;\n    match value {\n        Value::Object(map) => Ok(map),\n        _ => bail!(\"--data must be a JSON object\"),\n    }\n}\n\n/// Insert a flag value into a JSON body if it was provided on the CLI.\npub fn set<T: serde::Serialize>(body: &mut Map<String, Value>, key: &str, value: &Option<T>) {\n    if let Some(v) = value {\n        body.insert(key.to_string(), serde_json::to_value(v).unwrap());\n    }\n}\n\n/// Push a query parameter if the flag was provided.\npub fn push<T: ToString>(query: &mut Query, key: &str, value: &Option<T>) {\n    if let Some(v) = value {\n        query.push((key.to_string(), v.to_string()));\n    }\n}\n\n/// How one endpoint implements the deprecated offset paging it still accepts,","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube-cli/src/util.rs#L10-L46","documentation":"parse_data normalizes the --data flag value (string or already-parsed) into a serde_json Map. After deserializing the raw text as JSON (which would first fail with \"--data is not valid JSON\" if malformed), it requires the top-level value to be a JSON object. Scalars, arrays, or other non-object values are rejected because every request body the CLI builds is an object.","triggerScenarios":"Passing --data a top-level JSON array (`'[1,2]'`), a scalar (`'42'`, `'\"str\"'`), or any non-object value. Valid inline JSON that is not an object triggers exactly this bail.","commonSituations":"Users passing a JSON array of records intending bulk upload; quoting issues causing the shell to hand the flag a scalar; copy-pasted payloads whose root is an array.","solutions":["Wrap the value in a JSON object, e.g. --data '{\"key\": \"value\"}'","If you meant to send a list, find the field it belongs under: --data '{\"records\": [...]}'","Check shell quoting — the value must arrive as one argument containing valid JSON"],"exampleFix":"// before\ncube load --data '[{\"id\":1},{\"id\":2}]'\n\n// after\ncube load --data '{\"records\": [{\"id\":1},{\"id\":2}]}'","handlingStrategy":"validation","validationCode":"// validate --data before invoking\nclass IsObject {}\nfunction isJsonObject(s) {\n  try { const v = JSON.parse(s); return v !== null && typeof v === 'object' && !Array.isArray(v); }\n  catch { return false; }\n}\nif (!isJsonObject(dataArg)) throw new Error('--data must be a JSON object');","typeGuard":"function isJsonObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"match parse_data(&data_arg) {\n    Err(e) if e.to_string().contains(\"--data must be a JSON object\") => {\n        eprintln!(\"Pass a top-level JSON object, e.g. --data '{{\\\"key\\\": \\\"value\\\"}}'\");\n    }\n    Err(e) => return Err(e),\n    Ok(map) => { /* use map */ }\n}","preventionTips":["Always pass --data a JSON object literal with quoted keys","Wrap arrays under an object field instead of sending bare arrays","Single-quote the value in shells to avoid word-splitting/scalar coercion"],"tags":["cli","json","validation","argument-parsing"],"backgroundTag":"invalid-json-input","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}