tinyhumansai/openhuman · error
turn model source is missing a model
Error message
turn model source is missing a model
What it means
TurnModelSource::build fell through both branches: neither direct_model nor crate_native is set (mod.rs:1608, struct at 1389). TurnModelSource is a two-case sum emulated with Options; every constructor sets exactly one, so this error means the source was constructed empty — an internal wiring bug (a Default or struct literal with both fields None), not a user configuration problem.
Source
Thrown at src/openhuman/agent/tinyagents/mod.rs:1608
.split(':')
.next()
.unwrap_or(&provider_string)
.to_string()
};
return build_turn_models_crate(
&cn.role,
&cn.config,
model,
temperature,
context_window,
cn.primary_override.as_deref(),
provider_id,
!is_local,
!is_local,
cn.force_text_mode,
);
}
Err(anyhow::anyhow!("turn model source is missing a model"))
}
/// Build a standalone summarizer [`ChatModel`](tinyagents::harness::model::ChatModel)
/// over this source's provider — a fresh adapter (own error slot) for one-off
/// summary calls outside the main turn (e.g. the sub-agent cap-hit checkpoint),
/// so the caller can `invoke` without naming the `Provider` trait. The output
/// cap rides the per-call `ModelRequest`, not the model.
pub(crate) fn build_summarizer(
&self,
model: &str,
temperature: f64,
) -> anyhow::Result<Arc<dyn tinyagents::harness::model::ChatModel<()>>> {
if let Some(direct) = &self.direct_model {
let profile = direct.profile().cloned().unwrap_or_default();
return Ok(Arc::new(
ProfileOverrideModel::new(direct.clone(), profile)
.with_request_model(model)
.with_request_temperature(temperature),View on GitHub (pinned to a221052e0d)
Solutions
- Construct the source with a real constructor (direct-model injection or the new_crate_native* family) so exactly one branch is Some
- If you added a new source kind, extend build() with its branch before the final Err
- Add a constructor-level guard (debug_assert or explicit error) that at least one Option is set
Example fix
// before
let source = TurnModelSource { direct_model: None, crate_native: None, force_text_mode: false };
// after
let source = TurnModelSource::new_crate_native_from_string(role, provider_string, config); Defensive patterns
Strategy: validation
Validate before calling
// Internal: assert the source is configured before building turn models
fn assert_configured(source: &TurnModelSource) -> anyhow::Result<()> {
if source.direct_model.is_none() && source.crate_native.is_none() {
anyhow::bail!("TurnModelSource built without a model source — use a real constructor");
}
Ok(())
} Type guard
// Internal narrow: exactly-one-Option invariant of the two-case sum
impl TurnModelSource {
fn configured(&self) -> bool {
self.direct_model.is_some() ^ self.crate_native.is_some()
}
} Try / catch
// Add context so the invariant break is diagnosable at the call site
source.build(model, temp, ctx).await
.context("assembling turn harness: TurnModelSource had neither direct nor crate-native model")? Prevention
- Always construct TurnModelSource via its constructors — never struct literals or Default
- When adding a source kind, extend build() in the same change
- Keep a unit test per constructor asserting build() never hits the fallthrough Err
When it happens
Trigger: A new call site building TurnModelSource via struct literal or Default instead of the provided constructors; a refactor adding a third source kind without extending build(); test scaffolding meaning to inject a direct model but passing None.
Common situations: Feature work on the agent harness adding model-source paths; CI failures in newly added turn-assembly tests; code copied from a constructor that then gets its body stripped.
Related errors
- learning_save_profile: summarisation failed: {e:#}
- workflow scheduler graph compile failed: {e}
- tinyagents harness run failed: {e}
- Missing 'agent' parameter
- Missing 'prompt' parameter
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/42d9eff5b6007424.
Report an issue: GitHub.