From efb1542a39fb981587358d49414733f64835c939 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 27 May 2026 16:34:37 +0900 Subject: [PATCH] fix: empty-prompt error now returns non-null hint via newline-delimited usage string claw '' and claw ' ' returned empty_prompt + hint:null because the error message had no newline delimiter. Added usage hint. 61 CLI contract tests pass. --- rust/crates/rusty-claude-cli/src/main.rs | 3 +- .../tests/output_format_contract.rs | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index cd0e2ae7..d755da80 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -1378,8 +1378,9 @@ fn parse_args(args: &[String]) -> Result { // an empty prompt when credentials are present). let joined = rest.join(" "); if joined.trim().is_empty() { + // #798: add \n hint so split_error_hint extracts it (was empty_prompt + null) return Err( - "empty prompt: provide a subcommand (run `claw --help`) or a non-empty prompt string" + "empty prompt: provide a subcommand or a non-empty prompt string.\nUsage: claw or claw -p . Run `claw --help` for the full list." .to_string(), ); } diff --git a/rust/crates/rusty-claude-cli/tests/output_format_contract.rs b/rust/crates/rusty-claude-cli/tests/output_format_contract.rs index 21e821fd..b9354164 100644 --- a/rust/crates/rusty-claude-cli/tests/output_format_contract.rs +++ b/rust/crates/rusty-claude-cli/tests/output_format_contract.rs @@ -3418,3 +3418,36 @@ fn plugins_extra_args_have_non_null_hint_797() { "hint should reference plugins usage, got: {h:?}" ); } + +#[test] +fn empty_prompt_has_non_null_hint_798() { + // #798: `claw --output-format json ""` returned empty_prompt + hint:null. + // The error message "empty prompt: provide a subcommand..." had no \n delimiter. + let root = unique_temp_dir("empty-prompt-798"); + fs::create_dir_all(&root).expect("temp dir"); + std::process::Command::new("git") + .args(["init", "-q"]) + .current_dir(&root) + .output() + .ok(); + + let output = run_claw(&root, &["--output-format", "json", ""], &[]); + assert!( + !output.status.success(), + "empty prompt must exit non-zero (#798)" + ); + let stderr = String::from_utf8_lossy(&output.stderr); + let j: serde_json::Value = stderr + .lines() + .find(|l| l.trim_start().starts_with('{')) + .and_then(|l| serde_json::from_str(l).ok()) + .expect("empty prompt should emit JSON error envelope"); + assert_eq!(j["error_kind"], "empty_prompt"); + let h = j["hint"] + .as_str() + .expect("empty_prompt must have non-null hint (#798)"); + assert!( + h.contains("claw") || h.contains("Usage"), + "hint should reference usage, got: {h:?}" + ); +}