BoundaryML/baml · error

Invalid client property. Should have been a round-robin prop

Error message

Invalid client property. Should have been a round-robin property but got: {}

What it means

Type-mismatch guard while building a RoundRobin strategy client: after resolving the client property against the declared provider, the result was expected to be a RoundRobin property but resolved to a different shape. This means the client's declared provider and its property body disagree (e.g. provider = 'round-robin' but the body carries fallback-style fields), or resolution produced an unexpected variant.

Source

Thrown at engine/baml-runtime/src/internal/llm_client/strategy/roundrobin.rs:59

    pub fn current_index(&self) -> usize {
        self.current_index
            .load(std::sync::atomic::Ordering::Relaxed)
    }

    pub fn increment_index(&self) {
        self.current_index
            .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
    }
}

fn resolve_strategy(
    provider: &ClientProvider,
    properties: &UnresolvedClientProperty<()>,
    ctx: &RuntimeContext,
) -> Result<(Vec<ClientSpec>, usize)> {
    let properties = properties.resolve(provider, &ctx.eval_ctx(false))?;
    let ResolvedClientProperty::RoundRobin(props) = properties else {
        anyhow::bail!(
            "Invalid client property. Should have been a round-robin property but got: {}",
            properties.name()
        );
    };
    let start = match props.start_index {
        Some(start) => (start as usize) % props.strategy.len(),
        None => {
            if cfg!(target_arch = "wasm32") {
                // For VSCode, we don't want a random start point,
                // as it can make rendering inconsistent
                0
            } else {
                fastrand::usize(..props.strategy.len())
            }
        }
    };
    Ok((props.strategy, start))
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the strategy body is a round-robin property: `strategy { ClientA ClientB }` (optionally with start_index).
  2. If a fallback list was intended, change the provider to `fallback`.
  3. Check for copy-paste mixing of fallback and round-robin blocks.
  4. Regenerate and re-validate the .baml config.

Example fix

// before
client<Strategy> S {
  provider round-robin
  strategy fallback { A B }  // wrong shape
}

// after
client<Strategy> S {
  provider round-robin
  strategy { A B }
}
Defensive patterns

Strategy: validation

Validate before calling

const resolved = clientProperties.resolve();
if (resolved.kind !== 'round_robin') {
  throw new Error(`provider round-robin requires a round-robin strategy block, got ${resolved.kind}`);
}

Type guard

function isRoundRobinProperty(p) { return p && p.strategy === 'round_robin' && Array.isArray(p.strategyClients); }

Try / catch

try { loadClient('MyRRStrategy'); } catch (e) { if (String(e).includes('Should have been a round-robin property')) fixStrategyBlock(); }

Prevention

When it happens

Trigger: Declaring `strategy RoundRobin` whose properties resolve to something else — e.g. a fallback-shaped property assigned to a round-robin strategy client, or the strategy body missing the expected round-robin structure.

Common situations: Config where `provider round-robin` is set but the property body is a fallback block (or vice versa after copy-paste), or pointing a round-robin strategy at a plain (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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/613747b63cfb5868. Report an issue: GitHub.