tinyhumansai/openhuman · error
memory driver ` ` does not advertise the ` ` capability, so…
Error message
memory driver `{driver_id}` does not advertise the `{cap}` capability, so `{invocation}` is unavailable in this configuration. Run `openhuman subsystems` to see the bound driver and the families it advertises, or change `[subsystems.memory] driver` in your config. What it means
The CLI capability gate rejected an invocation because the memory driver bound for this workspace does not advertise the required capability. Denial is only possible because driver resolution succeeded - the gate is deliberately default-OPEN and skips entirely when the binding cannot be resolved. The message names the bound driver id and the missing capability, and points at `openhuman subsystems` for diagnosis and `[subsystems.memory] driver` for reconfiguration.
Solutions
- Run `openhuman subsystems` to see the bound driver id, class, and the capability families it advertises.
- Either change `[subsystems.memory] driver` to a driver that advertises the required capability, or use a different invocation.
- If a module should have provided the capability, check module load status and the compiled-in registry.
- Note that this denial proves resolution succeeded - an unreadable config would have skipped the gate (default-OPEN), so do not suspect config readability here.
Example fix
# before [subsystems] memory.driver = "module" # then: openhuman memory-diff ... -> capability error # after [subsystems] memory.driver = "embedded" # advertises diff/tree/recall
Defensive patterns
Strategy: validation
Validate before calling
let (driver_id, _class, advertised) = resolve_bound_driver() // same source cli_capability uses
.expect("gate skipped when unresolvable");
if !advertised.contains(&required_capability) {
// pick a driver that advertises it, or a different invocation - do not call Prevention
- Check `openhuman subsystems` output after any driver switch and before scripted invocations.
- Encode required capabilities per CLI command so scripts can pre-flight the bound driver.
- Remember the gate is default-OPEN on unresolvable bindings - a silent skip means config problems, not a pass.
When it happens
Trigger: Config binds a module-backed or otherwise non-embedded memory driver, then a CLI invocation runs that requires a capability only the embedded TinyCortex driver advertises (e.g. diff/tree families); or the backing module failed to load so the bound driver advertises fewer families than expected.
Common situations: Switching memory backends for a workspace; kernel or slim builds where the module providing a capability is absent; drift between the configured driver and the installed module set.
Related errors
- memory driver ` ` is not the embedded TinyCortex driver, so…
- agent ` ` is a `worker` tier and must not list ` ` in its…
- At least one of --expression, --tz, --command, or --name…
- --auth-token must not be empty
- [chat-factory] model
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/7e6ceccdc247fc94.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/cli_capability.rs:111
/// with the RPC registry about what is gated.
pub fn capability_verdict(
driver_id: &str,
advertised: Capabilities,
required: Option<Capability>,
invocation: &str,
) -> Result<()> {
let Some(capability) = required else {
return Ok(());
};
if advertised.contains(capability) {
return Ok(());
}
log::warn!(
"[cli][capability-gate] rejected invocation='{invocation}' driver='{driver_id}' \
capability={} — not advertised by the bound driver",
capability.as_str()
);
anyhow::bail!(capability_unavailable_message(
driver_id, capability, invocation
))
}
/// The driver bound for this machine's configured workspace:
/// `(id, class, advertised)`.
///
/// `None` means "could not resolve" — a missing or unreadable config, or a
/// workspace that will not bind. **The caller then skips the gate entirely**,
/// matching [`crate::core::all::capability_allowed`]'s default-OPEN posture:
/// denying is only ever correct after a driver has actually answered
/// `capabilities()`. A CLI that refused commands because it could not read
/// config would be strictly worse than one that lets the command run and fail
/// on its own terms.
pub async fn bound_memory_driver() -> Option<(String, DriverClass, Capabilities)> {
let config = match crate::openhuman::config::Config::load_or_init().await {
Ok(config) => config,
Err(err) => {View on GitHub (pinned to 7491200858)