Hmbown/CodeWhale · error · anyhow::Error
--input-json must be a JSON object
Error message
--input-json must be a JSON object
What it means
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.
Source
Thrown at crates/tui/src/lib.rs:10616
exit_workflow_tool_failure();
}
}
}
async fn run_workflow_tool_command_inner(
cli: &Cli,
args: WorkflowToolArgs,
plugin_registry: std::sync::Arc<crate::plugins::PluginRegistry>,
) -> Result<()> {
use crate::tools::spec::ToolSpec;
if args.approval_source != "explicit-workflow-command" {
bail!("workflow-tool requires --approval-source explicit-workflow-command");
}
let input: serde_json::Value = serde_json::from_str(&args.input_json)
.context("--input-json must be a valid Workflow tool input object")?;
if !input.is_object() {
bail!("--input-json must be a JSON object");
}
if !input
.get("action")
.and_then(serde_json::Value::as_str)
.is_some_and(|action| action.eq_ignore_ascii_case("run"))
{
bail!("workflow-tool accepts only action=run");
}
let workspace = resolve_workspace(cli);
let mut config = load_config_from_cli(cli)?;
merge_user_workspace_config(&mut config, cli.config.clone(), &workspace);
if let Ok(env_url) =
std::env::var("CODEWHALE_BASE_URL").or_else(|_| std::env::var("DEEPSEEK_BASE_URL"))
{
let trimmed = env_url.trim();
if !trimmed.is_empty() {
config.base_url = Some(trimmed.to_string());View on GitHub (pinned to 0c42157ee5)
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
Example fix
# before
codewhale workflow-tool --approval-source explicit-workflow-command --input-json '[{"action":"run"}]'
# after
codewhale workflow-tool --approval-source explicit-workflow-command --input-json '{"action":"run","input":{}}' Defensive patterns
Strategy: validation
Validate before calling
jq -e 'type == "object"' <<<"$INPUT_JSON" >/dev/null || { echo '--input-json must be a JSON object'; exit 1; } Type guard
const isInputObject = (s) => {
try { const v = JSON.parse(s); return v !== null && typeof v === 'object' && !Array.isArray(v); }
catch { return false; }
}; Prevention
- Validate with `jq type` before invoking workflow-tool
- Generate the JSON with jq -n or a serializer instead of string concatenation
When it happens
Trigger: Passing `--input-json '[1,2]'`, `--input-json '"run"'`, or a generator emitting a JSON array of action objects instead of a single object.
Common situations: Hand-built JSON inside shell quotes; a model emitting a batch list of tool calls where one object is expected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- workflow-tool accepts only action=run
- fleet task spec must include at least one task
- workflow-tool requires --approval-source explicit-workflow-c
- The Codewhale service returned an account without an ID
- `codewhale account` does not accept the global `--api-key` f
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/7198d76cc57f13f4.
Report an issue: GitHub.