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

  1. Run `openhuman subsystems` to see the bound driver and the capability families it advertises
  2. Change [subsystems.memory] driver in your config to one that advertises the required capability (e.g. back to the embedded driver)
  3. 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

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


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/7e6ceccdc247fc94. Report an issue: GitHub.