{"record":{"id":"bb4fffbb9546c72a","repo":"Hmbown/CodeWhale","slug":"config-path-cannot-be-empty","errorCode":null,"errorMessage":"config path cannot be empty","messagePattern":"config path cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/lib.rs","lineNumber":6757,"sourceCode":"                    child_key.clone()\n                } else {\n                    format!(\"{key}.{child_key}\")\n                };\n                redacted.insert(\n                    child_key.clone(),\n                    redact_toml_value_for_display_inner(&path, sensitive, child_value),\n                );\n            }\n            toml::Value::Table(redacted)\n        }\n        _ if sensitive => toml::Value::String(\"********\".to_string()),\n        _ => value.clone(),\n    }\n}\n\nfn normalize_config_file_path(path: PathBuf) -> Result<PathBuf> {\n    if path.as_os_str().is_empty() {\n        bail!(\"config path cannot be empty\");\n    }\n    if path\n        .components()\n        .any(|component| matches!(component, Component::ParentDir))\n    {\n        bail!(\"config path cannot contain '..' components\");\n    }\n    if path.file_name().is_none() {\n        bail!(\"config path must include a file name\");\n    }\n    let absolute = if path.is_absolute() {\n        path\n    } else {\n        std::env::current_dir()\n            .context(\"failed to resolve current directory for config path\")?\n            .join(path)\n    };\n    let file_name = absolute","sourceCodeStart":6739,"sourceCodeEnd":6775,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/lib.rs#L6739-L6775","documentation":"normalize_config_file_path validates a user-supplied config file path before resolving it against the current directory. An empty path (PathBuf::from(\"\") or whitespace-equivalent OS string) cannot name a file, so the library rejects it immediately. This fails loud at the earliest point per the repository's misconfiguration rule.","triggerScenarios":"Calling the config-loading entry point with PathBuf::new(), PathBuf::from(\"\"), or a CLI/env-derived --config value that expanded to an empty string.","commonSituations":"An unset CONFIG environment variable being read as \"\", a shell expanding an unquoted empty variable into the --config flag, or code constructing the path by joining an empty base directory.","solutions":["Pass an actual path to the config file, e.g. \"/home/user/.config/codewhale/config.toml\"","Check the env var / CLI flag source for an empty value before calling the loader","If the default config should be used, omit the path argument instead of passing \"\""],"exampleFix":"// before\nlet path = std::env::var(\"CODEWHALE_CONFIG\").unwrap_or_default();\nload_config(PathBuf::from(path))\n// after\nlet path = std::env::var(\"CODEWHALE_CONFIG\")\n    .ok()\n    .filter(|p| !p.is_empty())\n    .map(PathBuf::from)\n    .unwrap_or_else(default_config_path);","handlingStrategy":"validation","validationCode":"fn usable_config_path(p: &std::path::Path) -> bool {\n    !p.as_os_str().is_empty() && p.file_name().is_some()\n}","typeGuard":"fn non_empty_path(p: &str) -> Option<std::path::PathBuf> {\n    if p.trim().is_empty() { None } else { Some(std::path::PathBuf::from(p)) }\n}","tryCatchPattern":"match normalize_config_file_path(path) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"config path cannot be empty\") => {\n        eprintln!(\"--config was empty; using default\");\n        default_config_path()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Filter empty env-var values before converting to PathBuf","Quote CLI flags so unset variables fail loudly instead of passing \"\"","Default to the standard config location when no explicit path is given"],"tags":["config","path","validation"],"backgroundTag":"empty-required-field","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}