Hmbown/CodeWhale · error
agent profile provider must be a simple provider id
Error message
agent profile {} provider must be a simple provider id What it means
validate_agent_profile_provider (crates/tui/src/fleet/profile.rs:562) requires the provider value to be a 'simple provider id': no leading/trailing whitespace and only characters accepted by is_agent_profile_token_char. Anything else — padded strings, slashes, dots, spaces, unicode — is rejected so the launch path can resolve `[providers.<id>]` from the session config (#3965).
Solutions
- Trim the provider value and use a bare token (letters/digits/dash/underscore as allowed by is_agent_profile_token_char)
- Use the provider's registry id exactly as it appears under [providers.<id>] in the session config
- Do not encode model names, paths, or URLs in the provider field
Example fix
# before provider = "openai/gpt-4" # after provider = "openai"
Defensive patterns
Strategy: validation
Validate before calling
fn is_simple_provider_id(s: &str) -> bool {
let t = s.trim();
t == s && !t.is_empty() && t.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
} Type guard
fn is_simple_token(s: &str) -> bool { !s.trim().is_empty() && s.trim() == s && s.chars().all(is_agent_profile_token_char) } Try / catch
match agent_profile_from_toml(path) {
Ok(p) => p,
Err(e) if e.to_string().contains("must be a simple provider id") => {
eprintln!("{}: provider must be a bare id, no spaces/paths", path.display());
return;
}
Err(e) => return Err(e),
} Prevention
- Use the provider's registry id exactly as it appears under [providers.<id>]
- Never put model names, URLs, or qualified paths in the provider field
- Trim values when generating profiles programmatically
When it happens
Trigger: agent_profile_from_toml encounters a provider value that differs from its trimmed form (leading/trailing spaces) or contains characters outside the allowed token charset.
Common situations: Writing `provider = "openai "` with a trailing space from an editor; using a qualified name like `openai/gpt-4` or a URL as provider; pasting model strings into the provider field.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- agent profile provider cannot be empty
- duplicate fleet task id
- duplicate fleet worker id
- fleet cannot be empty
- fleet task ' ' coordination contracts must be one non-empty…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/d59a916f2aec6f56.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/profile.rs:562
);
}
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());
}
if trimmed != value || !trimmed.chars().all(is_agent_profile_token_char) {
bail!(
"agent profile {} provider must be a simple provider id",
path.display()
);
}
Ok(())
}
fn normalize_agent_profile_reasoning_effort(
path: &Path,
value: Option<&str>,
) -> Result<Option<String>> {
let Some(value) = non_empty_trimmed(value) else {
return Ok(None);
};
if matches!(
value.to_ascii_lowercase().as_str(),
"inherit" | "parent" | "same" | "current" | "default" | "unset"
) {View on GitHub (pinned to 73e0f67d83)