{"record":{"id":"f038289626fc7577","repo":"Hmbown/CodeWhale","slug":"agent-profile-field-cannot-be-empty","errorCode":null,"errorMessage":"agent profile {} {field} cannot be empty","messagePattern":"agent profile (.+?) (.+?) cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/profile.rs","lineNumber":466,"sourceCode":"            bail!(\n                \"agent profile {} may not request trust=true\",\n                path.display()\n            );\n        }\n        if permissions.approval_required == Some(false) {\n            bail!(\n                \"agent profile {} may not disable approval_required\",\n                path.display()\n            );\n        }\n    }\n    Ok(())\n}\n\nfn validate_agent_profile_token(path: &Path, field: &str, value: &str) -> Result<()> {\n    let trimmed = value.trim();\n    if trimmed.is_empty() {\n        bail!(\"agent profile {} {field} cannot be empty\", path.display());\n    }\n    if trimmed != value || !trimmed.chars().all(is_agent_profile_token_char) {\n        bail!(\n            \"agent profile {} {field} must be a simple token\",\n            path.display()\n        );\n    }\n    Ok(())\n}\n\nfn validate_agent_profile_model_hint(path: &Path, value: Option<&str>) -> Result<()> {\n    let Some(value) = value else {\n        return Ok(());\n    };\n    if !is_model_hint(value) {\n        bail!(\n            \"agent profile {} model must be a visible model id without whitespace or secrets\",\n            path.display()","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/profile.rs#L448-L484","documentation":"validate_agent_profile_token guards the id/name and base_role/role_hint fields of an agent profile. The effective id is id, else name, else the file stem. If that value is empty after trimming, load fails so the roster never contains a blank identity.","triggerScenarios":"A profile whose effective id/name trims to nothing: id = \"\" (or name = \"   \" with no id), or a profile file whose stem is blank (for example a file saved as .toml), which becomes the fallback id. Also fires for identity files scanned from roster directories via the same validator.","commonSituations":"A template profile created with a placeholder empty id; a file accidentally saved as .toml so the stem fallback is empty; generated profiles where the id field was never filled in.","solutions":["Set id = \"<slug>\" to a non-empty token in the profile TOML named in the error","If the id comes from name or the filename, give the file a real stem (rename .toml to scout.toml)","Check the path in the error message - it identifies the exact failing file"],"exampleFix":"# before (.codewhale/agents/.toml)\nname = \"\"\n\n# after (.codewhale/agents/scout.toml)\nid = \"scout\"","handlingStrategy":"validation","validationCode":"fn effective_profile_id(id: Option<&str>, name: Option<&str>, stem: &str) -> bool {\n    let effective = [id, name].into_iter().flatten().find(|v| !v.trim().is_empty());\n    effective.map(|v| !v.trim().is_empty()).unwrap_or(!stem.trim().is_empty())\n}","typeGuard":"fn is_profile_token(s: &str) -> bool {\n    let t = s.trim();\n    !t.is_empty() && t == s\n        && t.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.'))\n}","tryCatchPattern":"match load_agent_profile_file(&path) {\n    Ok(p) => Ok(p),\n    Err(err) if err.to_string().contains(\"cannot be empty\") => {\n        Err(anyhow!(\"profile {path:?} has a blank id/name - set id or rename the file\"))\n    }\n    Err(err) => Err(err),\n}","preventionTips":["Always set an explicit id in generated profiles instead of relying on the filename stem","Never save profile files with blank stems like .toml","Assert is_profile_token on ids before writing profile files"],"tags":["agent-profile","toml","validation","fleet","required-field"],"backgroundTag":"empty-required-field","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}