BoundaryML/baml · error
Expected a string, not null
Error message
Expected a string, not null
What it means
as_static_str cannot return a string for a null value; encountering UnresolvedValue::Null means the BAML field is explicitly null where a string is required, so it bails. This prevents null leaking into APIs that require non-optional strings.
Solutions
- Provide the required string value in the .baml file instead of null
- Check for null before reading (match on the variant or use resolve_null first) and apply a default in code
- Make the field non-null in the schema so mistakes surface at validation time
Example fix
// before (baml)
options {
model null
}
// after (baml)
options {
model "gpt-4o"
} Defensive patterns
Strategy: validation
Validate before calling
// Rust
if matches!(v, UnresolvedValue::Null(..)) {
anyhow::bail!("required string field is null");
}
let s = v.as_static_str()?; Type guard
fn is_present_string<Meta>(v: &UnresolvedValue<Meta>) -> bool {
matches!(v, UnresolvedValue::String(StringOr::Value(_), _))
} Try / catch
// Rust
let s = v.as_static_str()
.with_context(|| "required string field missing in baml config")?;
// provide default on error:
let s = v.as_static_str().unwrap_or("default-value"); Prevention
- Never leave required string options as null
- Apply defaults in code for optional fields before reading
- Enforce non-null in schema validation
When it happens
Trigger: Calling as_static_str() on UnresolvedValue::Null(..) — a BAML field set to null (or left as a null literal) but consumed through the string accessor.
Common situations: Unset configuration rendered as null, optional fields read without checking presence, or generated/config-as-code output emitting null for missing values.
Related errors
- Expected a map
- Expected a null value
- Expected a statically defined string, not env variable
- Expected a string, not a bool
- Expected a string, not a map
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4e76f5215b65b7b4.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-lib/baml-types/src/value_expr.rs:531
impl<Meta> UnresolvedValue<Meta> {
pub fn as_static_str(&self) -> Result<&str> {
match self {
Self::String(StringOr::Value(v), ..) => Ok(v.as_str()),
Self::String(StringOr::EnvVar(..), ..) => {
anyhow::bail!("Expected a statically defined string, not env variable")
}
Self::String(StringOr::JinjaExpression(..), ..) => {
anyhow::bail!("Expected a statically defined string, not expression")
}
Self::String(StringOr::TemplateStringCall { .. }, ..) => {
anyhow::bail!("Expected a statically defined string, not a template_string call")
}
Self::Numeric(num, ..) => Ok(num.as_str()),
Self::Array(..) => anyhow::bail!("Expected a string, not an array"),
Self::Bool(..) => anyhow::bail!("Expected a string, not a bool"),
Self::Map(..) => anyhow::bail!("Expected a string, not a map"),
Self::Null(..) => anyhow::bail!("Expected a string, not null"),
Self::ClassConstructor(..) => {
anyhow::bail!("Expected a string, not a class constructor")
}
}
}
pub fn resolve_string(&self, ctx: &impl GetEnvVar) -> Result<String> {
match self.resolve(ctx) {
Ok(ResolvedValue::String(s, ..)) => Ok(s),
_ => Err(anyhow::anyhow!("Expected a string")),
}
}
pub fn resolve_bool(&self, ctx: &impl GetEnvVar) -> Result<bool> {
match self.resolve(ctx) {
Ok(ResolvedValue::Bool(b, ..)) => Ok(b),
_ => Err(anyhow::anyhow!("Expected a boolean")),
}View on GitHub (pinned to bd85ce9dee)