{"record":{"id":"dbcc21fff8fbf364","repo":"xpipe-io/xpipe","slug":"directory-path-does-not-exist","errorCode":null,"errorMessage":"Directory ${path} does not exist","messagePattern":"Directory (.+?) does not exist","errorType":"exception","errorClass":"BeaconClientException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/mcp/McpTools.java","lineNumber":244,"sourceCode":"                                .build();\n                    }\n                }))\n                .build();\n    }\n\n    public static McpServerFeatures.SyncToolSpecification listFiles() throws IOException {\n        var tool = McpSchemaFiles.loadTool(\"list_files.json\");\n        return McpServerFeatures.SyncToolSpecification.builder()\n                .tool(tool)\n                .callHandler(McpToolHandler.of((req) -> {\n                    var system = req.getStringArgument(\"system\");\n                    var shellStore = req.getShellStoreRef(system, false);\n                    var shellSession = AppBeaconServer.get().getCache().getOrStart(shellStore);\n                    var fs = new ShellFileSystem(shellSession.getControl());\n                    var path = req.getFilePath(shellSession.getControl(), \"path\");\n\n                    if (!fs.directoryExists(path)) {\n                        throw new BeaconClientException(\"Directory \" + path + \" does not exist\");\n                    }\n\n                    try (var stream = fs.listFiles(fs, path)) {\n                        var list = stream.toList();\n                        var builder = McpSchema.CallToolResult.builder();\n                        for (FileEntry e : list) {\n                            builder.addTextContent(e.getPath().toString());\n                        }\n                        return builder.build();\n                    }\n                }))\n                .build();\n    }\n\n    public static McpServerFeatures.SyncToolSpecification findFile() throws IOException {\n        var tool = McpSchemaFiles.loadTool(\"find_file.json\");\n        return McpServerFeatures.SyncToolSpecification.builder()\n                .tool(tool)","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/mcp/McpTools.java#L226-L262","documentation":"The MCP listFiles tool checks fs.directoryExists(path) on the target shell before enumerating; if the path is not an existing directory it throws this BeaconClientException with the resolved path. This also fires when the path exists but is a regular file, since it must be a directory.","triggerScenarios":"Calling the MCP listFiles tool with a 'path' that is missing on the shell, or that points to a regular file instead of a directory; tilde-expanded path resolved against the connection user's home.","commonSituations":"Listing '~' paths whose home differs from expectation; pointing at a file (e.g. /etc/hosts) rather than a directory; directory removed or renamed on the remote; wrong connection selected.","solutions":["Verify the directory exists on that connection (e.g. readFile a known file or run an ls via another tool) before listing","Use an absolute directory path rather than a relative or '~'-based guess","If the path is a file, read it with readFile instead of listing it","Catch BeaconClientException and fall back to listing the parent directory to discover the correct name"],"exampleFix":"// before\n{\"system\": \"my-ssh\", \"path\": \"~/logs\"} // directory absent\n// after\n{\"system\": \"my-ssh\", \"path\": \"/var/log\"}","handlingStrategy":"validation","validationCode":"// verify the path is an existing directory before listing\nconst parent = path.substring(0, path.lastIndexOf('/')) || '/';\nconst entries = await listFiles(system, parent); // throws if parent missing\nconst target = entries.find(e => e.path === path);\nif (!target || !target.isDirectory) {\n  throw new Error(`'${path}' is not a directory on '${system}'`);\n}","typeGuard":"function isDirectoryEntry(e) { return e != null && e.isDirectory === true; }","tryCatchPattern":"try { return listFiles(system, path); } catch (BeaconClientException e) { if (e.message.includes('does not exist')) { /* fall back to listing the parent or reading as a file */ } throw e; }","preventionTips":["Distinguish files from directories before choosing readFile vs listFiles","Use absolute directory paths; verify '~' resolves to the expected home","Confirm the directory still exists on the remote before scripted listing"],"tags":["mcp","directory-not-found","remote-shell"],"backgroundTag":"directory-not-found","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"}