Hmbown/CodeWhale · error
agent profile {} model must be a visible model id without wh
Error message
agent profile {} model must be a visible model id without whitespace or secrets What it means
validate_agent_profile_model_hint checks the profile's model field with is_model_hint: every character must be ASCII graphic except '=', '\'' and '"'. The quote/equals ban exists so API keys and quoted ids cannot ride along inside a profile. The loader trims and drops blank model values first, so this error fires on inner whitespace, quotes, or '=' characters.
Source
Thrown at crates/tui/src/fleet/profile.rs:482
let trimmed = value.trim();
if trimmed.is_empty() {
bail!("agent profile {} {field} cannot be empty", path.display());
}
if trimmed != value || !trimmed.chars().all(is_agent_profile_token_char) {
bail!(
"agent profile {} {field} must be a simple token",
path.display()
);
}
Ok(())
}
fn validate_agent_profile_model_hint(path: &Path, value: Option<&str>) -> Result<()> {
let Some(value) = value else {
return Ok(());
};
if !is_model_hint(value) {
bail!(
"agent profile {} model must be a visible model id without whitespace or secrets",
path.display()
);
}
Ok(())
}
/// Validate an explicit `provider` field as a safe provider id (#4093).
///
/// Built-in providers are accepted by the runtime vocabulary, and user-named
/// OpenAI-compatible custom providers are accepted as simple tokens so the
/// launch path can resolve `[providers.<id>]` from the session config (#3965).
/// This field remains the ONLY place a profile's provider is established:
/// callers never infer it from `model` (EPIC #2608).
fn validate_agent_profile_provider(path: &Path, value: &str) -> Result<()> {
let trimmed = value.trim();
if trimmed.is_empty() {
bail!("agent profile {} provider cannot be empty", path.display());View on GitHub (pinned to 0c42157ee5)
Solutions
- Set model to a bare model id with no surrounding quotes, e.g. model = "gpt-4o"
- Remove any whitespace, '=' or quote characters from the value - keep only visible printable characters
- Store credentials in the provider config ([providers.<id>]), never in the profile's model field
Example fix
# before model = "'claude-sonnet-4'" # after model = "claude-sonnet-4"
Defensive patterns
Strategy: validation
Validate before calling
fn is_model_hint(value: &str) -> bool {
let t = value.trim();
!t.is_empty()
&& t == value
&& t.chars().all(|c| c.is_ascii_graphic() && !matches!(c, '=' | '\'' | '"'))
}
// assert is_model_hint(model) before writing the profile or calling load Type guard
fn is_visible_model_id(s: &str) -> bool {
let t = s.trim();
!t.is_empty() && t == s
&& t.chars().all(|c| c.is_ascii_graphic() && !matches!(c, '=' | '\'' | '"'))
} Try / catch
match load_agent_profile_file(&path) {
Ok(p) => Ok(p),
Err(err) if err.to_string().contains("visible model id") => {
Err(anyhow!("profile {path:?}: model must be a bare id - no quotes, spaces, or '='"))
}
Err(err) => Err(err),
} Prevention
- Paste model ids unquoted and never append credentials to them
- Reject '=' and quote characters at the input boundary when users author model hints
- Keep provider auth in [providers.<id>] config, not in profile model fields
When it happens
Trigger: model = "gpt-4o (preview)" (inner space), model = "'claude-sonnet-4'" (quotes pasted from docs), model = "gpt-4o key=abc" (equals sign / embedded key material), or any model id containing a non-printable or non-ASCII character.
Common situations: Copying a model id that was quoted in documentation or a changelog; accidentally appending provider credentials to the model string; model ids with parenthetical suffixes.
Related errors
- provider auth source secret must include secret_id
- agent profile {} {field} cannot be empty
- agent profile {} {field} must be a simple token
- agent profile {} provider cannot be empty
- agent profile {} provider must be a simple provider id
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/b44d9bfcc391bcd8.
Report an issue: GitHub.