{"record":{"id":"7e6ceccdc247fc94","repo":"tinyhumansai/openhuman","slug":"memory-driver-driver-id-does-not-advertise-the","errorCode":null,"errorMessage":"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.","messagePattern":"memory driver `(.+?)` does not advertise the `(.+?)` capability, so `(.+?)` 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\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/core/cli_capability.rs","lineNumber":111,"sourceCode":"/// with the RPC registry about what is gated.\npub fn capability_verdict(\n    driver_id: &str,\n    advertised: Capabilities,\n    required: Option<Capability>,\n    invocation: &str,\n) -> Result<()> {\n    let Some(capability) = required else {\n        return Ok(());\n    };\n    if advertised.contains(capability) {\n        return Ok(());\n    }\n    log::warn!(\n        \"[cli][capability-gate] rejected invocation='{invocation}' driver='{driver_id}' \\\n         capability={} — not advertised by the bound driver\",\n        capability.as_str()\n    );\n    anyhow::bail!(capability_unavailable_message(\n        driver_id, capability, invocation\n    ))\n}\n\n/// The driver bound for this machine's configured workspace:\n/// `(id, class, advertised)`.\n///\n/// `None` means \"could not resolve\" — a missing or unreadable config, or a\n/// workspace that will not bind. **The caller then skips the gate entirely**,\n/// matching [`crate::core::all::capability_allowed`]'s default-OPEN posture:\n/// denying is only ever correct after a driver has actually answered\n/// `capabilities()`. A CLI that refused commands because it could not read\n/// config would be strictly worse than one that lets the command run and fail\n/// on its own terms.\npub async fn bound_memory_driver() -> Option<(String, DriverClass, Capabilities)> {\n    let config = match crate::openhuman::config::Config::load_or_init().await {\n        Ok(config) => config,\n        Err(err) => {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/core/cli_capability.rs#L93-L129","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n# config.toml: [subsystems.memory] driver = \"remote-lite\"  (no `diff` family)\nopenhuman memory memory_diff ...\n# after\n# config.toml: [subsystems.memory] driver = \"embedded\"\nopenhuman memory memory_diff ...","handlingStrategy":"validation","validationCode":"# bash: inspect the bound driver's advertised families before memory commands\nopenhuman subsystems 2>/dev/null | grep -q \"$REQUIRED_CAP\" \\\n  || { echo \"bound memory driver does not advertise '$REQUIRED_CAP' — see 'openhuman subsystems'\" >&2; exit 2; }\nopenhuman memory \"$@\"","typeGuard":null,"tryCatchPattern":"if ! out=$(openhuman memory \"$fn\" 2>&1); then\n  case \"$out\" in\n    *\"does not advertise\"*) echo \"driver lacks capability for '$fn' — check [subsystems.memory] driver\" >&2 ;;\n    *) printf '%s\\n' \"$out\" >&2 ;;\n  esac\n  exit 1\nfi","preventionTips":["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"],"tags":["configuration","capability-gate","memory","cli"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}