fix(#763): config JSON parse errors now classify as config_parse_error

This commit is contained in:
YeonGyu-Kim
2026-05-27 01:16:04 +09:00
parent 88ce181031
commit c86dc73d8c
2 changed files with 19 additions and 2 deletions

View File

@@ -7691,3 +7691,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
761. **`mcp show <nonexistent>` and `skills show <nonexistent>` returned `hint: null`** — dogfooded 2026-05-27 on `7fa81b5d`. `server_not_found` envelope in `render_mcp_show_json` and `skill_not_found` envelope in `print_skills` JSON path both lacked `hint` fields, unlike `agent_not_found`/`plugin_not_found` fixed in #760. Fix: added `"hint": "Run \`claw mcp list\` to see configured servers."` to `server_not_found` and `"hint": "Run \`claw skills list\` to see available skills."` to `skill_not_found`. All four `*_not_found` envelopes now have hints. Source: Jobdori dogfood sweep on `7fa81b5d`, 2026-05-27.
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.

View File

@@ -302,6 +302,9 @@ fn classify_error_kind(message: &str) -> &'static str {
"api_http_error"
} else if message.contains("mcpServers") {
"malformed_mcp_config"
} else if message.contains(".claw/settings.json") || message.contains(".claw.json") {
// #763: config file JSON parse / validation errors (e.g. unterminated string, type mismatch)
"config_parse_error"
} else if message.starts_with("empty prompt") {
"empty_prompt"
} else if message.starts_with("interactive_only:") || message.contains("stdin is not a TTY") {
@@ -322,6 +325,8 @@ fn classify_error_kind(message: &str) -> &'static str {
"unknown_plugins_action"
} else if message.starts_with("missing_prompt:") {
"missing_prompt"
} else if message.starts_with("unknown_option:") {
"unknown_option"
} else if message.contains("is a slash command")
|| message.starts_with("interactive_only:")
// #735: "slash command /X is interactive-only" emitted by interactive-only guard
@@ -2012,7 +2017,7 @@ fn parse_export_args(args: &[String], output_format: CliOutputFormat) -> Result<
index += 1;
}
other if other.starts_with('-') => {
return Err(format!("unknown export option: {other}"));
return Err(format!("unknown_option: unknown export option: {other}.\nRun `claw export --help` for usage."));
}
other if output_path.is_none() => {
output_path = Some(PathBuf::from(other));
@@ -2055,7 +2060,7 @@ fn parse_dump_manifests_args(
index += 1;
continue;
}
return Err(format!("unknown dump-manifests option: {arg}"));
return Err(format!("unknown_option: unknown dump-manifests option: {arg}.\nRun `claw dump-manifests --help` for usage."));
}
Ok(CliAction::DumpManifests {
@@ -12915,6 +12920,16 @@ mod tests {
),
"missing_prompt"
);
assert_eq!(
classify_error_kind("/tmp/.claw/settings.json: expected ',', found end of input"),
"config_parse_error"
);
assert_eq!(
classify_error_kind(
"/path/to/.claw.json: field \"model\" must be a string, got a number"
),
"config_parse_error"
);
}
#[test]