{"record":{"id":"27756d213e076e2c","repo":"xpipe-io/xpipe","slug":"multiple-stores-found-storenames","errorCode":null,"errorMessage":"Multiple stores found: \" + storeNames","messagePattern":"Multiple stores found: \" \\+ storeNames","errorType":"exception","errorClass":"BeaconClientException","httpStatus":400,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/api/TerminalExternalLaunchExchange.java","lineNumber":37,"sourceCode":"\nimport java.util.List;\n\npublic class TerminalExternalLaunchExchange extends BeaconInterface<TerminalExternalLaunchExchange.Request> {\n\n    @Override\n    public String getPath() {\n        return \"/terminal/externalLaunch\";\n    }\n\n    @Override\n    public Object handle(HttpExchange exchange, Request msg) throws BeaconClientException, BeaconServerException {\n        var found = DataStorageQuery.queryUserInput(msg.getConnection());\n        if (found.isEmpty()) {\n            throw new BeaconClientException(\"No connection found for input \" + msg.getConnection());\n        }\n\n        if (found.size() > 1) {\n            throw new BeaconClientException(\"Multiple stores found: \"\n                    + found.stream().map(DataStoreEntry::getName).toList());\n        }\n\n        var e = found.getFirst();\n        var isShell = e.getStore() instanceof ShellStore;\n        if (!isShell) {\n            throw new BeaconClientException(\n                    \"Connection \" + DataStorage.get().getStorePath(e).toString() + \" is not a shell connection\");\n        }\n\n        if (!checkPermission()) {\n            return Response.builder().command(List.of()).build();\n        }\n\n        var r = TerminalLauncherManager.externalExchange(e.ref(), msg.getArguments());\n        return Response.builder().command(r).build();\n    }\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/api/TerminalExternalLaunchExchange.java#L19-L55","documentation":"Thrown by the beacon server when handling a /terminal/externalLaunch request: resolving the user-supplied connection input via DataStorageQuery.queryUserInput matched more than one data store, so the request is ambiguous and no single connection can be selected for the external terminal launch. It fires when the user's input (e.g. a name or partial identifier) is not unique across configured stores; the exception lists the matching store names so the caller can disambiguate.","triggerScenarios":"Calling terminal/external launch with a partial or ambiguous 'connection' string (e.g. a bare name that exists in multiple categories, or a pattern matching several stores).","commonSituations":"Two connections with the same display name in different categories; passing a short name that also matches category names or multiple entries; duplicate imports of the same connection.","solutions":["Use the fully qualified store path (category/connection) instead of the bare name","Use the connection's UUID, which is unique","Deduplicate/rename the connections so names are unique","Narrow the query with a more specific path"],"exampleFix":"// before\nclient.terminalLaunch(\"webserver\"); // matches 2 entries\n// after\nclient.terminalLaunch(\"Servers/webserver\"); // unique path","handlingStrategy":"validation","validationCode":"var found = DataStorageQuery.queryUserInput(input);\nif (found.size() > 1) throw new IllegalArgumentException(\"ambiguous: \" + input);","typeGuard":null,"tryCatchPattern":"try {\n    client.terminalLaunch(input);\n} catch (BeaconClientException ex) {\n    if (ex.getMessage().startsWith(\"Multiple stores found\")) {\n        // retry with a fully-qualified path\n    } else throw ex;\n}","preventionTips":["Prefer UUIDs over display names","Enforce unique connection names per category","Use qualified paths (Category/Name) in scripts"],"tags":["terminal","ambiguity","connection","xpipe"],"backgroundTag":"empty-result-set","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}