{"record":{"id":"56ea8d0247701837","repo":"Hmbown/CodeWhale","slug":"agent-profile-path-is-not-a-directory","errorCode":null,"errorMessage":"agent profile path {} is not a directory","messagePattern":"agent profile path (.+?) is not a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/profile.rs","lineNumber":299,"sourceCode":"    let dir = dir.as_ref();\n    let mut profiles = Vec::new();\n    let mut seen = BTreeSet::new();\n    for path in agent_profile_paths(dir)? {\n        let profile = load_agent_profile_file(&path)?;\n        if !seen.insert(profile.id.to_ascii_lowercase()) {\n            bail!(\"duplicate agent profile id {}\", profile.id);\n        }\n        profiles.push(profile);\n    }\n    Ok(profiles)\n}\n\nfn agent_profile_paths(dir: &Path) -> Result<Vec<PathBuf>> {\n    if !dir.exists() {\n        return Ok(Vec::new());\n    }\n    if !dir.is_dir() {\n        bail!(\"agent profile path {} is not a directory\", dir.display());\n    }\n\n    let mut paths = std::fs::read_dir(dir)\n        .with_context(|| format!(\"reading agent profile dir {}\", dir.display()))?\n        .collect::<std::io::Result<Vec<_>>>()\n        .with_context(|| format!(\"reading agent profile entries in {}\", dir.display()))?\n        .into_iter()\n        .map(|entry| entry.path())\n        .filter(|path| path.extension().and_then(|value| value.to_str()) == Some(\"toml\"))\n        .collect::<Vec<_>>();\n    paths.sort();\n    Ok(paths)\n}\n\nfn load_agent_profile_identity_file(path: &Path) -> Result<AgentProfileIdentity> {\n    let raw = std::fs::read_to_string(path)\n        .with_context(|| format!(\"reading agent profile identity {}\", path.display()))?;\n    let parsed: AgentProfileIdentityToml = toml::from_str(&raw)","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/profile.rs#L281-L317","documentation":"agent_profile_paths expects the configured profiles location to be a directory of TOML files. The path exists but is a regular file, so read_dir cannot proceed and the loader bails with the offending path. A missing path is fine (empty profile set); a file is not.","triggerScenarios":"Configuring the agent profiles setting to a single TOML file path instead of its containing directory.","commonSituations":"Users pointing the setting directly at profiles/default.toml; migrating from a single-file profile config to the directory layout; a symlink pointing at a file.","solutions":["Point the setting at the directory containing the profile TOMLs, not at a file","If you only have one profile file, put it in a directory and reference the directory","Verify with ls -ld that the path resolves to a directory"],"exampleFix":"# before\n[fleet]\nagent_profiles = \"~/.config/codewhale/profiles/default.toml\"\n\n# after\n[fleet]\nagent_profiles = \"~/.config/codewhale/profiles\"","handlingStrategy":"validation","validationCode":"use std::path::Path;\n\nfn profiles_path_is_dir(path: &Path) -> bool {\n    !path.exists() || path.is_dir() // missing is fine; a file is not\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = load_agent_profiles_from_dir(&configured) {\n    if err.to_string().contains(\"is not a directory\") {\n        eprintln!(\"point the agent profiles setting at a directory of TOML files\");\n    }\n    return Err(err.into());\n}","preventionTips":["Configure the profiles setting to a directory, never a single TOML file","Verify configuration paths with ls -ld after editing settings"],"tags":["fleet","agent-profiles","misconfigured-path","configuration","rust","codewhale"],"backgroundTag":"config-path-invalid","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}