Skip to content

Commit c70312b

Browse files
committed
fix(#754): missing_credentials hint now newline-delimited so JSON hint field is non-null
1 parent e932713 commit c70312b

3 files changed

Lines changed: 19 additions & 4 deletions

File tree

ROADMAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7673,3 +7673,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
76737673
752. **`claw <subcommand> --output-format json <bogus-arg>` returned `hint: null` for all `cli_parse` errors when an unrecognized positional arg was supplied** — dogfooded 2026-05-26 on `ddc71b56`. Generic `unrecognized argument` format string had no `\n` so `split_error_hint` emitted null hint (only the `--json` special-case added a hint). Fix: add else-branch appending `\nRun `claw <verb> --help` for usage.` to the generic arm. Affected surfaces: `sandbox`, `doctor`, `version`, and any other subcommand routing through the same unrecognized-arg path. Source: Jobdori dogfood on `ddc71b56`, 2026-05-26.
76747674

76757675
753. **`claw --output-format json -p` (no prompt arg) returned `error_kind:"unknown"` and `hint: null`** — parity gap with #750/#751 which fixed the explicit `prompt` verb. Identified by gaebal-gajae on `ddc71b56`. Fix: same `missing_prompt:` prefix + newline usage hint as #750. Regression guard: `short_p_flag_no_arg_json_error_kind_753` asserting nonzero exit, `error_kind:"missing_prompt"`, non-empty hint mentioning `claw -p` or `claw prompt`. Source: gaebal-gajae dogfood on `ddc71b56`, 2026-05-26.
7676+
7677+
754. **`missing_credentials` JSON envelope always had `hint: null` even when a contextual hint was available** — dogfooded 2026-05-26 on `e9327135`. `ApiError::Display` for `MissingCredentials` appended the hint via ` — hint: {hint}` (inline, no `\n`), so `split_error_hint()` could not extract it and left the JSON `hint` field null. Fix: change delimiter from ` — hint: ` to `\n` in `api/src/error.rs` Display impl; update two tests in `api/src/error.rs` and `api/src/providers/mod.rs` to assert newline separator. Source: Jobdori dogfood on `e9327135`, 2026-05-26.

rust/crates/api/src/error.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,10 @@ impl Display for ApiError {
273273
}
274274
}
275275
if let Some(hint) = hint {
276-
write!(f, " — hint: {hint}")?;
276+
// #754: newline-delimited so split_error_hint() can extract the hint
277+
// into the JSON envelope's `hint` field. The em-dash form was a
278+
// single-line string that left hint:null in --output-format json.
279+
write!(f, "\n{hint}")?;
277280
}
278281
Ok(())
279282
}
@@ -608,11 +611,16 @@ mod tests {
608611
rendered.starts_with("missing Anthropic credentials;"),
609612
"hint should be appended, not replace the base message: {rendered}"
610613
);
611-
let hint_marker = " — hint: I see OPENAI_API_KEY is set — if you meant to use the OpenAI-compat provider, prefix your model name with `openai/` so prefix routing selects it.";
614+
// #754: hint is now newline-delimited so split_error_hint() can extract it
615+
let hint_text = "I see OPENAI_API_KEY is set — if you meant to use the OpenAI-compat provider, prefix your model name with `openai/` so prefix routing selects it.";
612616
assert!(
613-
rendered.ends_with(hint_marker),
617+
rendered.ends_with(hint_text),
614618
"rendered error should end with the hint: {rendered}"
615619
);
620+
assert!(
621+
rendered.contains('\n'),
622+
"rendered error must contain newline separator so split_error_hint works: {rendered}"
623+
);
616624
// Classification semantics are unaffected by the presence of a hint.
617625
assert_eq!(error.safe_failure_class(), "provider_auth");
618626
assert!(!error.is_retryable());

rust/crates/api/src/providers/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,10 +1649,15 @@ NO_EQUALS_LINE
16491649
rendered.starts_with("missing Anthropic credentials;"),
16501650
"canonical base message should still lead the rendered error: {rendered}"
16511651
);
1652+
// #754: hint delimiter changed from " — hint: " to "\n" so split_error_hint works
16521653
assert!(
1653-
rendered.contains(" — hint: I see OPENAI_API_KEY is set"),
1654+
rendered.contains("I see OPENAI_API_KEY is set"),
16541655
"rendered error should carry the env-driven hint: {rendered}"
16551656
);
1657+
assert!(
1658+
rendered.contains('\n'),
1659+
"rendered error must use newline separator (#754): {rendered}"
1660+
);
16561661
}
16571662

16581663
#[test]

0 commit comments

Comments
 (0)