BoundaryML/baml · error
default_role must be one of 'system', 'user' or 'assistant':
Error message
default_role must be one of 'system', 'user' or 'assistant': {}. Please specify "allowed_roles" if you want to use other custom default role. What it means
When a BAML LLM client config specifies a `default_role` but no `allowed_roles`, only the built-in chat roles 'system', 'user', and 'assistant' are accepted. Any other default role string is rejected at client spec resolution time. To use a custom default role, you must explicitly list it in `allowed_roles`.
Source
Thrown at engine/baml-lib/llm-client/src/clientspec.rs:370
.transpose()?;
let remap: Option<HashMap<String, String>> = remap.map(|remap| {
remap
.into_iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
});
match (&allowed, &default) {
(Some(allowed), Some(default)) => {
if !allowed.contains(default) {
return Err(anyhow::anyhow!("default_role must be in allowed_roles: {}. Not found in {:?}", default, allowed));
}
}
(None, Some(default)) => {
match default.as_str() {
"system" | "user" | "assistant" => {}
_ => return Err(anyhow::anyhow!("default_role must be one of 'system', 'user' or 'assistant': {}. Please specify \"allowed_roles\" if you want to use other custom default role.", default)),
}
}
_ => {}
}
match (&allowed, &remap) {
(Some(allowed), Some(remap)) => {
for k in remap.keys() {
if !allowed.contains(k) {
return Err(anyhow::anyhow!(
"remap_role must be in allowed_roles: {}. Not found in {:?}",
k,
allowed
));
}
}
}
(None, Some(remap)) => {View on GitHub (pinned to bd85ce9dee)
Solutions
- Change default_role to one of 'system', 'user', or 'assistant'.
- Add an allowed_roles array that includes the custom default role you want.
- Fix casing/typos in the default_role value (roles are matched exactly).
Example fix
// before
client<llm> MyClient {
provider openai
default_role "developer"
}
// after
client<llm> MyClient {
provider openai
default_role "system"
}
// or, to keep the custom role:
client<llm> MyClient {
provider openai
allowed_roles ["system", "user", "assistant", "developer"]
default_role "developer"
} Defensive patterns
Strategy: validation
Validate before calling
const DEFAULT_ROLES = ["system", "user", "assistant"];
if (!allowedRoles && defaultRole && !DEFAULT_ROLES.includes(defaultRole)) {
throw new Error(`default_role '${defaultRole}' requires allowed_roles`);
} Prevention
- Keep default_role within the standard three roles unless you also define allowed_roles.
- Lint BAML client blocks for role values against the standard set.
When it happens
Trigger: Resolving a client spec where allowed_roles is unset and default_role is a string other than 'system', 'user', or 'assistant' (e.g. 'developer', 'function').
Common situations: Copying client configs from providers whose role vocabulary differs from OpenAI's (e.g. newer role names), or typos like 'System'/'users' in BAML client blocks.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- remap_role must be in allowed_roles: {}. Not found in {:?}
- Invalid allowed role metadata: {}. Allowed values are 'all'
- script `{target}` has no `--function` and there is no implic
- test profile `{name}` was requested, but {} does not exist
- test profile `{name}` is not defined in {} (available: {avai
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b80609a4e017c1c3.
Report an issue: GitHub.