xpipe-io/xpipe · error · BeaconClientException

Not a toggleable connection

Error message

Not a toggleable connection

What it means

Thrown by the connection state toggle MCP tool when the referenced store is not a SingletonSessionStore, i.e. it has no single start/stop session lifecycle. Only toggleable connections (like shell connections with a singleton session) support switching state on/off.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/mcp/McpTools.java:505

                    return McpSchema.CallToolResult.builder()
                            .addTextContent("Terminal is launching")
                            .build();
                }))
                .build();
    }

    public static McpServerFeatures.SyncToolSpecification toggleState() throws IOException {
        var tool = McpSchemaFiles.loadTool("toggle_state.json");
        return McpServerFeatures.SyncToolSpecification.builder()
                .tool(tool)
                .callHandler(McpToolHandler.of((req) -> {
                    var system = req.getStringArgument("system");
                    var state = req.getBooleanArgument("state");
                    var ref = req.getDataStoreRef(system);

                    if (!(ref.getStore() instanceof SingletonSessionStore<?> singletonSessionStore)) {
                        throw new BeaconClientException("Not a toggleable connection");
                    }
                    if (state) {
                        singletonSessionStore.startSessionIfNeeded();
                    } else {
                        singletonSessionStore.stopSessionIfNeeded();
                    }

                    return McpSchema.CallToolResult.builder()
                            .addTextContent("Connection state set to " + state)
                            .build();
                }))
                .build();
    }
}

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Pass a system reference that resolves to a toggleable connection (SingletonSessionStore)
  2. Check the connection type in XPipe before toggling — use only shell-type connections
  3. Use the connection's UUID or a resolvable store reference rather than a name that may match a category
  4. If the connection is always active, skip the toggle call

Example fix

// before
toggleConnection(system: "My Home Category", state: false) // not a store
// after
toggleConnection(system: "ssh-webserver-uuid", state: false)
Defensive patterns

Strategy: type-guard

Validate before calling

function isToggleableConnection(store) {
  return typeof store === 'object' && store !== null && store.kind === 'singletonSession';
}
// only call the toggle tool when the referenced system resolves to a session-backed connection

Type guard

function canToggle(systemInfo) {
  return Boolean(systemInfo && systemInfo.sessionBased === true);
}

Try / catch

try {
  await mcp.call('setConnectionState', {system, state});
} catch (e) {
  if (String(e.message) === 'Not a toggleable connection') {
    // resolve an individual shell connection instead of a category/store
  }
}

Prevention

When it happens

Trigger: Calling the toggle tool with a 'system' argument whose resolved data store is a plain data store or a non-session store type (e.g. a simple file store, or a composite/category store).

Common situations: Pointing the tool at a non-connection data store, a category/collection instead of an individual connection, or a connection type that is always-on and has no toggleable session.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/19765e274f4d2e17. Report an issue: GitHub.