BoundaryML/baml · error
Invalid client property. Should have been a fallback propert
Error message
Invalid client property. Should have been a fallback property but got: {} What it means
`FallbackStrategy::try_from` resolves a client's strategy properties and requires them to be of the `fallback` variant. If the resolved property is any other kind (e.g. round-robin or a plain client), this error is thrown naming the actual variant.
Source
Thrown at engine/baml-runtime/src/internal/llm_client/strategy/fallback.rs:32
runtime_interface::InternalClientLookup,
RuntimeContext,
};
pub struct FallbackStrategy {
pub name: String,
pub(super) retry_policy: Option<String>,
// TODO: We can add conditions to each client
client_specs: Vec<ClientSpec>,
}
fn resolve_strategy(
provider: &ClientProvider,
properties: &UnresolvedClientProperty<()>,
ctx: &RuntimeContext,
) -> Result<Vec<ClientSpec>> {
let properties = properties.resolve(provider, &ctx.eval_ctx(false))?;
let ResolvedClientProperty::Fallback(props) = properties else {
anyhow::bail!(
"Invalid client property. Should have been a fallback property but got: {}",
properties.name()
);
};
Ok(props.strategy)
}
impl TryFrom<(&ClientProperty, &RuntimeContext)> for FallbackStrategy {
type Error = anyhow::Error;
fn try_from(
(client, ctx): (&ClientProperty, &RuntimeContext),
) -> std::result::Result<Self, Self::Error> {
let strategy = resolve_strategy(&client.provider, &client.unresolved_options()?, ctx)?;
Ok(Self {
name: client.name.clone(),
retry_policy: client.retry_policy.clone(),
client_specs: strategy,View on GitHub (pinned to bd85ce9dee)
Solutions
- Make the client's strategy property an actual `fallback` block with a `strategy` list of clients.
- If you intended round-robin, use the round-robin strategy client instead.
- Check spelling/structure of the strategy block in the .baml file and re-generate.
- Verify the client referenced via `client <name>` in a strategy is itself declared with the matching strategy properties.
Example fix
// before
client<MyLLMStrategy> Strategy {
provider fallback
strategy round_robin { ... } // mismatch
}
// after
client<MyLLMStrategy> Strategy {
provider fallback
strategy {
ClientA
ClientB
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the strategy client before use
const resolved = clientProperties.resolve();
if (resolved.kind !== 'fallback') {
throw new Error(`provider fallback requires a fallback strategy block, got ${resolved.kind}`);
} Type guard
function isFallbackProperty(p) { return p && p.strategy === 'fallback' && Array.isArray(p.strategyClients); } Try / catch
try { loadClient('MyStrategy'); } catch (e) { if (String(e).includes('Should have been a fallback property')) fixBamlStrategyBlock(); } Prevention
- Match strategy blocks exactly to the provider keyword (fallback ↔ fallback shape)
- Run `baml-cli generate`/`baml-cli dev` to validate config before runtime
- Avoid copy-pasting between fallback and round-robin blocks without renaming
When it happens
Trigger: Declaring a `strategy Fallback` (or a client referenced as fallback) whose properties resolve to a non-fallback shape — e.g. the BAML block defines a `strategy RoundRobin` but code paths construct a FallbackStrategy from it.
Common situations: Copy-pasting a client config where `strategy` keyword says fallback but the body/property type is round-robin (or vice versa), or pointing a strategy client at a non-strategy client property.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unsupported strategy provider: {}
- Unsupported strategy provider: {}. Available ones are: {}
- Invalid client property. Should have been a round-robin prop
- Configuration error: {0}
- Strategy provider is empty: {}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/68f01ebf6d94fd77.
Report an issue: GitHub.