{"record":{"id":"5ab3b1129107a72a","repo":"xpipe-io/xpipe","slug":"file-path-does-already-exist","errorCode":null,"errorMessage":"File ${path} does already exist","messagePattern":"File (.+?) does already exist","errorType":"exception","errorClass":"BeaconClientException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/mcp/McpTools.java","lineNumber":347,"sourceCode":"                            .structuredContent(map)\n                            .build();\n                }))\n                .build();\n    }\n\n    public static McpServerFeatures.SyncToolSpecification createFile() throws IOException {\n        var tool = McpSchemaFiles.loadTool(\"create_file.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, true);\n                    var shellSession = AppBeaconServer.get().getCache().getOrStart(shellStore);\n                    var path = req.getFilePath(shellSession.getControl(), \"path\");\n                    var fs = new ShellFileSystem(shellSession.getControl());\n\n                    if (fs.fileExists(path)) {\n                        throw new BeaconClientException(\"File \" + path + \" does already exist\");\n                    }\n\n                    fs.touch(path);\n\n                    if (req.getRawRequest().arguments().containsKey(\"content\")) {\n                        var s = req.getRawRequest().arguments().get(\"content\").toString();\n                        var b = s.getBytes(StandardCharsets.UTF_8);\n                        try (var out = fs.openOutput(path, b.length)) {\n                            out.write(b);\n                        }\n                    }\n\n                    return McpSchema.CallToolResult.builder()\n                            .addTextContent(\"File created successfully\")\n                            .build();\n                }))\n                .build();\n    }","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/mcp/McpTools.java#L329-L365","documentation":"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.","triggerScenarios":"Calling createFile with a 'path' that already exists as a file on the target system.","commonSituations":"Re-running an idempotent script twice, automation retrying a succeeded call, or intending an update but calling create instead of a write/overwrite tool.","solutions":["Use a different file name or path","Delete the existing file first if overwrite is intended","Check existence beforehand and only call createFile when absent","If content should replace an existing file, use a write/update mechanism instead of createFile"],"exampleFix":"// before\ncreateFile(system: \"host\", path: \"/tmp/out.txt\") // second run fails\n// after\nif (!fileExists(system: \"host\", path: \"/tmp/out.txt\")) {\n  createFile(system: \"host\", path: \"/tmp/out.txt\", content: \"data\")\n}","handlingStrategy":"validation","validationCode":"async function createFileIfAbsent(mcp, system, path, content) {\n  const exists = await mcp.call('fileExists', {system, path}); // or shell test -f\n  if (exists) return; // skip or pick unique name\n  return mcp.call('createFile', {system, path, content});\n}","typeGuard":null,"tryCatchPattern":"try {\n  await mcp.call('createFile', {system, path});\n} catch (e) {\n  if (String(e.message).includes('does already exist')) {\n    // treat as success for idempotent scripts or use a unique name\n  }\n}","preventionTips":["Make automation idempotent: check-then-create or tolerate the conflict","Use unique/temporary names for generated files","Never rely on createFile to overwrite content"],"tags":["mcp","filesystem","conflict"],"backgroundTag":"file-already-exists","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}