tinyhumansai/openhuman · error · anyhow::Error
toolkit `{toolkit}` is not connected. Connected toolkits: [{
Error message
toolkit `{toolkit}` is not connected. Connected toolkits: [{}] What it means
render_integrations_agent (src/openhuman/agent/debug/mod.rs:272) looks up the requested toolkit in the agent's connected_integrations with a case-insensitive match AND `ci.connected == true`. A miss builds the connected-toolkit list (connected entries only) and errors with it, so the message doubles as a discovery aid.
Source
Thrown at src/openhuman/agent/debug/mod.rs:272
/// dynamic prompt builder.
async fn render_integrations_agent(config: &Config, toolkit: &str) -> Result<DumpedPrompt> {
let mut agent = Agent::from_config_for_agent(config, INTEGRATIONS_AGENT_ID)
.with_context(|| format!("building integrations_agent session for `{toolkit}`"))?;
agent.fetch_connected_integrations().await;
let mut integration = agent
.connected_integrations()
.iter()
.find(|ci| ci.connected && ci.toolkit.eq_ignore_ascii_case(toolkit))
.cloned()
.ok_or_else(|| {
let connected: Vec<String> = agent
.connected_integrations()
.iter()
.filter(|ci| ci.connected)
.map(|ci| ci.toolkit.clone())
.collect();
anyhow!(
"toolkit `{toolkit}` is not connected. Connected toolkits: [{}]",
connected.join(", ")
)
})?;
// Resolve the live client kind via the mode-aware factory so a
// direct-mode user can still render the prompt even without a
// backend session (#1710 Wave 2). Backend mode keeps the existing
// `fetch_toolkit_actions` round-trip; direct mode skips the
// refresh (no backend allowlist to consult) and keeps the cached
// catalogue, mirroring `ComposioListToolsTool`'s short-circuit.
use crate::openhuman::integrations::composio::client::{
create_composio_client, ComposioClientKind,
};
let client_kind = create_composio_client(config)
.map_err(|e| anyhow!("composio client unavailable — is the user signed in? ({e})"))?;
// Refresh the action catalogue for this toolkit at prompt-generationView on GitHub (pinned to a221052e0d)
Solutions
- Pick a toolkit from the error's Connected toolkits list.
- Run `composio list_connection` to see live connection state and connect the toolkit you want.
- Reconnect a toolkit showing as known-but-disconnected, then retry the dump.
- If the list is empty but you expect connections, sign in / refresh so the connected_integrations snapshot repopulates.
Example fix
# before ... --agent integrations_agent --toolkit google # error lists: [gmail, notion] # after ... --agent integrations_agent --toolkit gmail
Defensive patterns
Strategy: validation
Validate before calling
let connected: Vec<String> = agent
.connected_integrations()
.iter()
.filter(|ci| ci.connected)
.map(|ci| ci.toolkit.clone())
.collect();
if !connected.iter().any(|t| t.eq_ignore_ascii_case(&toolkit)) {
anyhow::bail!("toolkit `{toolkit}` not connected; connected: {connected:?}");
} Type guard
fn is_connected_toolkit(agent: &AgentHandle, toolkit: &str) -> bool {
agent
.connected_integrations()
.iter()
.any(|ci| ci.connected && ci.toolkit.eq_ignore_ascii_case(toolkit))
} Try / catch
match render_integrations_agent(&config, toolkit).await {
Err(e) if e.to_string().contains("is not connected") => {
// Parse the Connected toolkits list from the message, prompt the user
// to pick one or connect it, then retry with a valid toolkit.
}
other => other,
} Prevention
- Check `composio list_connection` before naming a toolkit.
- Remember the match requires ci.connected == true — known-but-disconnected toolkits fail too.
- Use exact toolkit slugs (gmail, notion), not vendor names (google).
When it happens
Trigger: Prompt-dumping `integrations_agent --toolkit X` where X is not connected at all, is known but whose connection is currently disabled/disconnected (ci.connected false), or where the backend session's connected_integrations snapshot is stale.
Common situations: Toolkit was revoked/disconnected after the app started; user guesses a toolkit name ("google" vs "gmail"); case variants are fine but prefixes/aliases are not; backend returned an empty snapshot so everything appears disconnected.
Related errors
- composio client unavailable — is the user signed in? ({e})
- integrations_agent requires a `toolkit` argument — e.g. `gma
- integrations_agent definition not in registry
- AgentDefinitionRegistry missing after init
- integrations_agent definition missing from registry
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/62366a8b688c2f37.
Report an issue: GitHub.