xpipe-io/xpipe · error · BeaconClientException

File ${path} does already exist

Error message

File ${path} does already exist

What it means

Thrown by the createFile MCP tool when the target path already exists as a file. XPipe refuses to overwrite silently, so fs.touch() is only run on a free path. Optional 'content' is only written after a successful touch.

Source

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

                            .structuredContent(map)
                            .build();
                }))
                .build();
    }

    public static McpServerFeatures.SyncToolSpecification createFile() throws IOException {
        var tool = McpSchemaFiles.loadTool("create_file.json");
        return McpServerFeatures.SyncToolSpecification.builder()
                .tool(tool)
                .callHandler(McpToolHandler.of((req) -> {
                    var system = req.getStringArgument("system");
                    var shellStore = req.getShellStoreRef(system, true);
                    var shellSession = AppBeaconServer.get().getCache().getOrStart(shellStore);
                    var path = req.getFilePath(shellSession.getControl(), "path");
                    var fs = new ShellFileSystem(shellSession.getControl());

                    if (fs.fileExists(path)) {
                        throw new BeaconClientException("File " + path + " does already exist");
                    }

                    fs.touch(path);

                    if (req.getRawRequest().arguments().containsKey("content")) {
                        var s = req.getRawRequest().arguments().get("content").toString();
                        var b = s.getBytes(StandardCharsets.UTF_8);
                        try (var out = fs.openOutput(path, b.length)) {
                            out.write(b);
                        }
                    }

                    return McpSchema.CallToolResult.builder()
                            .addTextContent("File created successfully")
                            .build();
                }))
                .build();
    }

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Use a different file name or path
  2. Delete the existing file first if overwrite is intended
  3. Check existence beforehand and only call createFile when absent
  4. If content should replace an existing file, use a write/update mechanism instead of createFile

Example fix

// before
createFile(system: "host", path: "/tmp/out.txt") // second run fails
// after
if (!fileExists(system: "host", path: "/tmp/out.txt")) {
  createFile(system: "host", path: "/tmp/out.txt", content: "data")
}
Defensive patterns

Strategy: validation

Validate before calling

async function createFileIfAbsent(mcp, system, path, content) {
  const exists = await mcp.call('fileExists', {system, path}); // or shell test -f
  if (exists) return; // skip or pick unique name
  return mcp.call('createFile', {system, path, content});
}

Try / catch

try {
  await mcp.call('createFile', {system, path});
} catch (e) {
  if (String(e.message).includes('does already exist')) {
    // treat as success for idempotent scripts or use a unique name
  }
}

Prevention

When it happens

Trigger: Calling createFile with a 'path' that already exists as a file on the target system.

Common situations: Re-running an idempotent script twice, automation retrying a succeeded call, or intending an update but calling create instead of a write/overwrite tool.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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