{"record":{"id":"09e4a79cdb3b6f18","repo":"Hmbown/CodeWhale","slug":"doctor-configuration-validation-failed-see-json-o","errorCode":null,"errorMessage":"doctor configuration validation failed; see JSON output","messagePattern":"doctor configuration validation failed; see JSON output","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":6551,"sourceCode":"/// Emit a bounded, secret-redacted JSON failure when configuration cannot be\n/// loaded or validated. Invalid configuration must not be forced through the\n/// normal doctor report because its route/capability facts would be misleading.\nfn run_doctor_json_config_error(error: &anyhow::Error) -> Result<()> {\n    let safe_message = error\n        .downcast_ref::<crate::config::SafeConfigDiagnostic>()\n        .map(ToString::to_string);\n    let report = serde_json::json!({\n        \"status\": \"error\",\n        \"error\": {\n            \"kind\": \"config_validation\",\n            \"message\": safe_message.as_deref().unwrap_or(\"configuration validation failed; details omitted because configuration errors may contain credential material\"),\n        },\n    });\n    println!(\"{}\", serde_json::to_string_pretty(&report)?);\n\n    // Keep stderr generic: the actionable, redacted error is already on\n    // stdout, and Rust's Result termination must never redisclose a secret.\n    bail!(\"doctor configuration validation failed; see JSON output\")\n}\n\n/// Machine-readable counterpart to `run_doctor`. This report is always\n/// structural and offline; live probe flags conflict with `--json`.\nfn run_doctor_json(\n    config: &Config,\n    workspace: &Path,\n    config_path_override: Option<&Path>,\n    plugins: &crate::plugins::PluginRegistry,\n) -> Result<()> {\n    use serde_json::json;\n\n    let doctor_paths = crate::doctor::DoctorPathReport::resolve(config_path_override)?;\n    let config_path = &doctor_paths.config;\n    let secret_backend = codewhale_secrets::diagnose_secret_backend();\n\n    let credential = resolve_credential_diagnostic(config);\n","sourceCodeStart":6533,"sourceCodeEnd":6569,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L6533-L6569","documentation":"`codewhale doctor` validates the loaded configuration before reporting; when validation fails it prints a redacted JSON error object to stdout and then bails with this deliberately generic stderr line. The split is intentional: configuration errors can contain credential material, so the sanitized detail (safe_message) only ever reaches stdout, and Rust's Result termination path stays secret-free.","triggerScenarios":"run_doctor reaches config validation and it returns Err: malformed TOML, an invalid route/provider setting, or an unreadable config file (including the config_path_override path). The stdout JSON carries kind \"config_validation\".","commonSituations":"Hand-edited config.toml with a typo; a codewhale upgrade changed the config schema; conflicting env overrides; a credential embedded in a provider URL that validation rejects.","solutions":["Re-run `codewhale doctor` and read `error.message` from the stdout JSON — that is where the redacted specifics live","Fix the config key the message names, in the config file doctor loaded","Pre-validate that the file parses (any TOML linter) and re-run doctor","If redaction hides the cause, temporarily remove the secret from config and re-run to surface the underlying error"],"exampleFix":"// before: stderr only shows the generic line\n$ codewhale doctor 2>&1 >/dev/null\ndoctor configuration validation failed; see JSON output\n\n// after: pull the actionable, redacted message from stdout\n$ codewhale doctor 2>/dev/null | jq -r '.error.message'","handlingStrategy":"try-catch","validationCode":"// preflight: parse the config file before invoking doctor\nlet raw = std::fs::read_to_string(&config_path)?;\ntoml::from_str::<toml::Value>(&raw)?; // surfaces the real syntax error here","typeGuard":null,"tryCatchPattern":"out=$(codewhale doctor 2>/dev/null); rc=$?\nif [ \"$rc\" -ne 0 ]; then\n  msg=$(printf '%s' \"$out\" | jq -r '.error.message // \"unknown\"')\n  echo \"doctor config validation failed: $msg\" >&2\nfi","preventionTips":["Never store credentials directly in config.toml; use the key store so validation errors stay descriptive","Re-run doctor after every config edit or version upgrade","Script against the stdout JSON, not stderr, when doctor fails"],"tags":["doctor","config","validation","secret-redaction","json-output"],"backgroundTag":"config-validation-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}