tinyhumansai/openhuman · error
memory driver `{driver_id}` does not advertise the `{cap}` c
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-side memory capability gate fired: the workspace's configured [subsystems.memory] driver resolved successfully and answered capabilities(), but the family required by this invocation is not among them, so the command is rejected before dispatch. Denial is only ever issued after a driver has actually advertised its capabilities — an unresolvable binding defaults OPEN (the gate is skipped), matching the core's capability_allowed posture. The message names the driver, the missing capability, and the invocation verbatim.
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 a221052e0d)
Solutions
- Run `openhuman subsystems` to see the bound driver and the capability families it advertises
- Change [subsystems.memory] driver in your config to one that advertises the required capability (e.g. back to the embedded driver)
- Or use only the commands the bound driver supports for this workflow
Example fix
# before # config.toml: [subsystems.memory] driver = "remote-lite" (no `diff` family) openhuman memory memory_diff ... # after # config.toml: [subsystems.memory] driver = "embedded" openhuman memory memory_diff ...
Defensive patterns
Strategy: validation
Validate before calling
# bash: inspect the bound driver's advertised families before memory commands
openhuman subsystems 2>/dev/null | grep -q "$REQUIRED_CAP" \
|| { echo "bound memory driver does not advertise '$REQUIRED_CAP' — see 'openhuman subsystems'" >&2; exit 2; }
openhuman memory "$@" Try / catch
if ! out=$(openhuman memory "$fn" 2>&1); then
case "$out" in
*"does not advertise"*) echo "driver lacks capability for '$fn' — check [subsystems.memory] driver" >&2 ;;
*) printf '%s\n' "$out" >&2 ;;
esac
exit 1
fi Prevention
- After changing [subsystems.memory] driver, run `openhuman subsystems` and re-check which families it advertises
- Encode the capability requirements of your scripts and verify them against the subsystems output
- Remember the gate is default-OPEN on unresolvable bindings — a green run on a broken config proves nothing
When it happens
Trigger: Config binds a non-embedded/remote memory driver that does not advertise, say, `search` or `diff`, and the user runs a CLI command in that family (e.g. a memory search/diff invocation); an older driver version that predates a newly required capability family.
Common situations: Switching [subsystems.memory] driver to a lighter remote driver and re-running existing memory scripts; upgrading the core so a command requires a capability the bound driver never implemented; sharing one config across machines with different driver bindings.
Related errors
- memory driver `{driver_id}` is not the embedded TinyCortex d
- OpenHuman could not reach its local runtime. Quit and reopen
- audio blob is empty
- voice_not_compiled
- audio blob is empty
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/7e6ceccdc247fc94.
Report an issue: GitHub.