xpipe-io/xpipe · error · BeaconClientException

Connection ${path} is not a shell connection

Error message

Connection ${path} is not a shell connection

What it means

McpToolHandler.getShellStoreRef resolves a connection ref and then asserts the underlying store is an instance of ShellStore. When the resolved connection is a different store kind (e.g. a database, HTTP, or script store), it throws this BeaconClientException naming the store path.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/mcp/McpToolHandler.java:158

            if (found.size() > 1) {
                throw new BeaconClientException("Multiple connections found: "
                        + found.stream()
                                .map(entry ->
                                        DataStorage.get().getStorePath(entry).toString())
                                .toList());
            }

            var e = found.getFirst();
            return e.ref();
        }

        public DataStoreEntryRef<ShellStore> getShellStoreRef(String name, boolean mutation)
                throws BeaconClientException {
            var ref = getDataStoreRef(name);
            var isShell = ref.getStore() instanceof ShellStore;
            if (!isShell) {
                throw new BeaconClientException("Connection "
                        + DataStorage.get().getStorePath(ref.get()).toString() + " is not a shell connection");
            }

            var disableMutation =
                    DataStorage.get().getEffectiveCategoryConfig(ref.get()).getDontAllowScripts();
            if (mutation && disableMutation != null && disableMutation) {
                throw new BeaconClientException("Modifications to connection "
                        + DataStorage.get().getStorePath(ref.get()).toString()
                        + " is disabled by the category setting");
            }

            return ref.asNeeded();
        }
    }
}

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Pass the name of an actual shell connection (SSH, local shell, serial, etc.)
  2. Inspect the connection's type in the XPipe UI; create an SSH/local shell connection if needed
  3. If the target is a database, use the database-specific MCP tool instead of the shell one
  4. Catch BeaconClientException and report that the chosen connection type is unsupported for shell operations

Example fix

// before
req.getShellStoreRef("prod-postgres", false) // database store
// after
req.getShellStoreRef("prod-postgres-host", false) // SSH shell connection to the host
Defensive patterns

Strategy: type-guard

Validate before calling

// check the connection type before the shell tool call
const conn = await getConnection(name);
if (conn.storeType !== 'shell') {
  throw new Error(`connection '${name}' is a ${conn.storeType} store; a shell connection is required`);
}

Type guard

function isShellConnection(conn) { return conn != null && typeof conn.storeType === 'string' && conn.storeType.toLowerCase().includes('shell'); }

Try / catch

try { return shellTool.call({name}); } catch (BeaconClientException e) { if (e.message.includes('is not a shell connection')) { /* switch to the matching tool for that store kind */ } throw e; }

Prevention

When it happens

Trigger: Calling an MCP shell tool (shell command execution, file read/list) and passing a connection name whose DataStore is not a ShellStore — e.g. a database connection, an API/http connection, or a custom store.

Common situations: Selecting a database or Kubernetes connection where a shell connection was expected; confusing a Proxmox/hypervisor container entry with its SSH connection; reusing a name from a different tool context.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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