fix(#764): config_parse_error now populates hint field via Display newline delimiter

This commit is contained in:
YeonGyu-Kim
2026-05-27 01:23:00 +09:00
parent c86dc73d8c
commit 4ea255ca6a
3 changed files with 42 additions and 1 deletions

View File

@@ -7693,3 +7693,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
762. **`classify_error_kind` unit test missing coverage for 15 of 23 classifier arms** — dogfooded 2026-05-27 on `d83de563`. `classify_error_kind_returns_correct_discriminants` only asserted 8 of the 23 arms, leaving `missing_flag_value`, `invalid_flag_value`, `missing_prompt`, `interactive_only`, `unknown_agents_subcommand`, `agent_not_found`, `plugin_not_found`, `skill_not_found`, `unsupported_config_section`, `no_managed_sessions`, `legacy_session_no_workspace_binding`, `missing_manifests`, `unknown_plugins_action`, `unsupported_skills_action`, and `confirmation_required` uncovered. Any discriminant string drift would silently fall to `"unknown"` without a failing test. Fix: added 18 new `assert_eq!` invocations covering all previously untested arms. Source: Jobdori test-brittleness sweep on `d83de563`, 2026-05-27.
763. **Config JSON parse errors fall to `error_kind:"unknown"`** — dogfooded 2026-05-27 on `88ce1810`. Malformed `.claw/settings.json` or `.claw.json` (unterminated string, type mismatch, unknown keys) produce serde_json errors like `"/path/.claw/settings.json: expected ',', found end of input"` but classify as `error_kind:"unknown"` + `hint:null`. Callers must regex the error message to route. Fix: added `config_parse_error` classifier arm that matches on presence of `.claw/settings.json` or `.claw.json` in the error message. All three error patterns now consistently produce `error_kind:"config_parse_error"`. Test coverage added. Source: Jobdori event/log opacity probe on `88ce1810`, 2026-05-27.
764. **`config_parse_error` returned `hint: null` despite #763 adding the classifier** — dogfooded 2026-05-27 on `c86dc73d`. #763 fixed `error_kind` classification but `hint` remained `null` because `ConfigError::Parse` Display impl emitted only the bare serde_json error string (no `\n` delimiter). `split_error_hint()` found nothing to split. Fix: updated `Display for ConfigError::Parse` in `runtime/src/config.rs` to append `\nFix: open the file shown above and correct the JSON syntax, then retry.`. Integration test `config_parse_error_has_typed_error_kind_and_hint_764` added to `output_format_contract.rs` asserting non-zero exit + `error_kind:config_parse_error` + non-empty hint. 31 contract tests pass. Source: Jobdori follow-up probe on `c86dc73d`, 2026-05-27.

View File

@@ -217,7 +217,10 @@ impl Display for ConfigError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Io(error) => write!(f, "{error}"),
Self::Parse(error) => write!(f, "{error}"),
Self::Parse(error) => write!(
f,
"{error}\nFix: open the file shown above and correct the JSON syntax, then retry."
),
}
}
}

View File

@@ -1829,3 +1829,39 @@ fn export_json_has_kind_702() {
);
}
}
#[test]
fn config_parse_error_has_typed_error_kind_and_hint_764() {
// #764: Malformed .claw/settings.json must emit error_kind:config_parse_error
// and a non-null hint in --output-format json mode (was error_kind:"unknown"
// + hint:null before #763/#764 fixes).
let root = unique_temp_dir("config-parse-error-764");
fs::create_dir_all(root.join(".claw")).expect("temp .claw dir should exist");
// Write an invalid JSON file (type mismatch: model must be a string)
fs::write(root.join(".claw").join("settings.json"), r#"{"model": 99}"#)
.expect("settings.json should write");
let output = run_claw(&root, &["--output-format", "json", "config", "show"], &[]);
assert!(
!output.status.success(),
"malformed settings.json should cause non-zero exit"
);
let stderr = String::from_utf8_lossy(&output.stderr);
let json_line = stderr
.lines()
.find(|l| l.trim_start().starts_with('{'))
.expect("stderr should contain a JSON error envelope");
let parsed: serde_json::Value =
serde_json::from_str(json_line).expect("error envelope should be valid JSON");
assert_eq!(
parsed["error_kind"], "config_parse_error",
"malformed settings.json must return error_kind:config_parse_error (#763)"
);
let hint = parsed["hint"].as_str().unwrap_or("");
assert!(
!hint.is_empty(),
"malformed settings.json must return non-null hint (#764), got: {hint:?}"
);
}