{"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":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":10616,"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":10598,"sourceCodeEnd":10634,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L10598-L10634","documentation":"workflow-tool parses --input-json with serde_json (a parse failure produces its own 'must be a valid Workflow tool input object' context error), then requires the top-level value to be an object. Arrays, strings, numbers, booleans, and null all pass parsing but fail this shape check.","triggerScenarios":"Passing `--input-json '[1,2]'`, `--input-json '\"run\"'`, or a generator emitting a JSON array of action objects instead of a single object.","commonSituations":"Hand-built JSON inside shell quotes; a model emitting a batch list of tool calls where one object is expected.","solutions":["Wrap the payload in an object containing at least {\"action\":\"run\", ...}","Pre-validate with `jq type` returning object","Check shell quoting: the JSON must arrive as one argument"],"exampleFix":"# before\ncodewhale workflow-tool --approval-source explicit-workflow-command --input-json '[{\"action\":\"run\"}]'\n\n# after\ncodewhale workflow-tool --approval-source explicit-workflow-command --input-json '{\"action\":\"run\",\"input\":{}}'","handlingStrategy":"validation","validationCode":"jq -e 'type == \"object\"' <<<\"$INPUT_JSON\" >/dev/null || { echo '--input-json must be a JSON object'; exit 1; }","typeGuard":"const isInputObject = (s) => {\n  try { const v = JSON.parse(s); return v !== null && typeof v === 'object' && !Array.isArray(v); }\n  catch { return false; }\n};","tryCatchPattern":null,"preventionTips":["Validate with `jq type` before invoking workflow-tool","Generate the JSON with jq -n or a serializer instead of string concatenation"],"tags":["workflow","json","validation","argument-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}