{"record":{"id":"b0adba2e1ffe4061","repo":"BoundaryML/baml","slug":"expected-a-statically-defined-string-not-expression","errorCode":null,"errorMessage":"Expected a statically defined string, not expression","messagePattern":"Expected a statically defined string, not expression","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/baml-types/src/value_expr.rs","lineNumber":522,"sourceCode":"\nimpl Default for EvaluationContext<'_> {\n    fn default() -> Self {\n        Self {\n            env_vars: None,\n            fill_missing_env_vars: true,\n        }\n    }\n}\n\nimpl<Meta> UnresolvedValue<Meta> {\n    pub fn as_static_str(&self) -> Result<&str> {\n        match self {\n            Self::String(StringOr::Value(v), ..) => Ok(v.as_str()),\n            Self::String(StringOr::EnvVar(..), ..) => {\n                anyhow::bail!(\"Expected a statically defined string, not env variable\")\n            }\n            Self::String(StringOr::JinjaExpression(..), ..) => {\n                anyhow::bail!(\"Expected a statically defined string, not expression\")\n            }\n            Self::String(StringOr::TemplateStringCall { .. }, ..) => {\n                anyhow::bail!(\"Expected a statically defined string, not a template_string call\")\n            }\n            Self::Numeric(num, ..) => Ok(num.as_str()),\n            Self::Array(..) => anyhow::bail!(\"Expected a string, not an array\"),\n            Self::Bool(..) => anyhow::bail!(\"Expected a string, not a bool\"),\n            Self::Map(..) => anyhow::bail!(\"Expected a string, not a map\"),\n            Self::Null(..) => anyhow::bail!(\"Expected a string, not null\"),\n            Self::ClassConstructor(..) => {\n                anyhow::bail!(\"Expected a string, not a class constructor\")\n            }\n        }\n    }\n\n    pub fn resolve_string(&self, ctx: &impl GetEnvVar) -> Result<String> {\n        match self.resolve(ctx) {\n            Ok(ResolvedValue::String(s, ..)) => Ok(s),","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/baml-types/src/value_expr.rs#L504-L540","documentation":"as_static_str only returns values that are literal strings (or numerics) written directly in BAML source. A Jinja expression (e.g. \"{{ something }}\") needs evaluation at runtime, so the static accessor rejects it. The library throws this because a static string is required where the value is used (e.g. names, enum tags, provider fields) and an expression cannot be known at parse time.","triggerScenarios":"Calling as_static_str() on UnresolvedValue::String(StringOr::JinjaExpression(..)) — a BAML field whose value is a Jinja template expression like {{ ctx.field }} or {{ _.name }} instead of a quoted literal.","commonSituations":"Developers interpolate dynamic values into BAML fields that must be static (client names, enum variant values, metadata strings), or copy template-style config between fields, then a static validation/registration pass fails.","solutions":["Replace the Jinja expression with a static quoted string literal in the .baml file","Move the dynamic interpolation to a place where it is allowed (e.g. prompt bodies, not static identifiers)","In consuming Rust code, use resolve_string(&ctx) (with a context that can render the expression) instead of as_static_str()"],"exampleFix":"// before (baml)\nenum Sentiment {\n  \"{{ Positive }}\"\n}\n// after (baml)\nenum Sentiment {\n  Positive\n}","handlingStrategy":"validation","validationCode":"// Rust\nif matches!(v, UnresolvedValue::String(StringOr::JinjaExpression(_), _)) {\n    anyhow::bail!(\"Jinja expressions are not allowed in this static field\");\n}\nlet s = v.as_static_str()?;","typeGuard":"fn is_static_string<Meta>(v: &UnresolvedValue<Meta>) -> bool {\n    matches!(v, UnresolvedValue::String(StringOr::Value(_), _))\n}","tryCatchPattern":null,"preventionTips":["Use Jinja only inside prompt bodies, never in static identifiers/options","Validate baml_src early with a linter that flags expressions in scalar fields","Resolve expressions at runtime with resolve_string when dynamism is required"],"tags":["rust","baml","jinja","template","static-analysis"],"backgroundTag":"unsupported-operation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}