{"record":{"id":"7198d76cc57f13f4","repo":"Hmbown/CodeWhale","slug":"input-json-must-be-a-json-object","errorCode":null,"errorMessage":"--input-json must be a JSON object","messagePattern":"--input-json must be a JSON object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":12229,"sourceCode":"            exit_workflow_tool_failure();\n        }\n    }\n}\n\nasync fn run_workflow_tool_command_inner(\n    cli: &Cli,\n    args: WorkflowToolArgs,\n    plugin_registry: std::sync::Arc<crate::plugins::PluginRegistry>,\n) -> Result<()> {\n    use crate::tools::spec::ToolSpec;\n\n    if args.approval_source != \"explicit-workflow-command\" {\n        bail!(\"workflow-tool requires --approval-source explicit-workflow-command\");\n    }\n    let input: serde_json::Value = serde_json::from_str(&args.input_json)\n        .context(\"--input-json must be a valid Workflow tool input object\")?;\n    if !input.is_object() {\n        bail!(\"--input-json must be a JSON object\");\n    }\n    if !input\n        .get(\"action\")\n        .and_then(serde_json::Value::as_str)\n        .is_some_and(|action| action.eq_ignore_ascii_case(\"run\"))\n    {\n        bail!(\"workflow-tool accepts only action=run\");\n    }\n\n    let workspace = resolve_workspace(cli);\n    let mut config = load_config_from_cli(cli)?;\n    merge_user_workspace_config(&mut config, cli.config.clone(), &workspace);\n    if let Ok(env_url) =\n        std::env::var(\"CODEWHALE_BASE_URL\").or_else(|_| std::env::var(\"DEEPSEEK_BASE_URL\"))\n    {\n        let trimmed = env_url.trim();\n        if !trimmed.is_empty() {\n            config.base_url = Some(trimmed.to_string());","sourceCodeStart":12211,"sourceCodeEnd":12247,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/lib.rs#L12211-L12247","documentation":"After passing the approval-source check, `workflow-tool` parses `--input-json` with serde_json and additionally requires the parsed value to be a JSON object (`input.is_object()`). Non-object JSON (arrays, strings, numbers) is rejected even though it is valid JSON.","triggerScenarios":"Passing `--input-json` that is a JSON array, scalar, or null — or unparseable text, which fails earlier with the `.context(...)` message — so `is_object()` returns false.","commonSituations":"Shell quoting mangling the JSON (quotes stripped so `{action:\"run\"}` is not valid JSON), or passing a top-level array of actions instead of a single object.","solutions":["Wrap the payload in a JSON object, e.g. `{\"action\": \"run\", ...}`.","Quote the whole `--input-json` value in single quotes in the shell to survive quoting.","Validate with `echo '<payload>' | jq -e 'type == \"object\"'` before invoking."],"exampleFix":"// before\ncodewhale workflow-tool --input-json '[{\"action\":\"run\"}]'\n// after\ncodewhale workflow-tool --approval-source explicit-workflow-command --input-json '{\"action\":\"run\"}'","handlingStrategy":"validation","validationCode":"const input = JSON.parse(inputJson);\nif (typeof input !== 'object' || input === null || Array.isArray(input)) {\n  throw new Error('--input-json must be a JSON object');\n}\n","typeGuard":"function isJsonObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n","tryCatchPattern":"match serde_json::from_str::<serde_json::Value>(&args.input_json) {\n    Ok(v) if v.is_object() => run(v),\n    Ok(_) => bail!(\"--input-json must be a JSON object\"),\n    Err(e) => bail!(\"invalid JSON: {e}\"),\n}\n","preventionTips":["Validate payloads with `jq -e 'type == \"object\"'` before invoking.","Single-quote the whole --input-json value in shells to survive quoting.","Always model workflow input as a top-level object with an `action` field."],"tags":["cli","json","workflow","invalid-argument"],"backgroundTag":"invalid-argument-format","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}