{"record":{"id":"5f9db61f12845101","repo":"xpipe-io/xpipe","slug":"directory-is-a-root","errorCode":null,"errorMessage":"Directory is a root","messagePattern":"Directory is a root","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/icon/SystemIconSource.java","lineNumber":56,"sourceCode":"\n    String getDescription();\n\n    void open();\n\n    @Value\n    @Builder\n    @Jacksonized\n    @JsonTypeName(\"directory\")\n    class Directory implements SystemIconSource {\n\n        Path path;\n        String id;\n\n        @Override\n        public void checkComplete() throws ValidationException {\n            Validators.nonNull(path);\n            if (path.getParent() == null) {\n                throw new ValidationException(\"Directory is a root\");\n            }\n            Validators.notEmpty(id);\n        }\n\n        @Override\n        public void refresh() {}\n\n        @Override\n        public Path getPath() {\n            return path;\n        }\n\n        @Override\n        public String getIcon() {\n            return \"mdi2f-folder\";\n        }\n\n        @Override","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/icon/SystemIconSource.java#L38-L74","documentation":"The directory icon source's checkComplete() validates that the chosen path has a parent. Passing a filesystem root (e.g. '/' or 'C:\\') yields path.getParent() == null, and a ValidationException is thrown because a root directory cannot serve as an icon source target.","triggerScenarios":"Calling checkComplete() on a DirectoryIconSource builder/state where path was set to a filesystem root via Paths.get(\"\") or a drive root.","commonSituations":"User selects '/' or a drive letter in the icon-source picker; code passing Path.of(\"\") (empty path resolves to the current root-relative path with no parent) instead of a real subdirectory.","solutions":["Select a non-root subdirectory as the icon source path","Use Path.of(\".\").toRealPath() and then descend into a subdirectory instead of an empty/root path","Add a UI-side guard rejecting root paths before completing the form"],"exampleFix":"// before\nvar path = Path.of(\"\");\nsource.path(path);\n// after\nvar path = Path.of(\".\").toRealPath().resolve(\"assets\");\nsource.path(path);","handlingStrategy":"validation","validationCode":"if (path == null || path.getParent() == null) throw new ValidationException(\"Directory is a root\");\nif (path.toString().isBlank()) throw new ValidationException(\"Path is empty\");","typeGuard":"boolean isNonRootDir(Path p) { return p != null && p.getParent() != null && Files.isDirectory(p); }","tryCatchPattern":"try { source.checkComplete(); } catch (ValidationException e) { /* show picker again, disallow root selection */ }","preventionTips":["Reject root/drive paths in directory pickers","Never pass Path.of(\"\") as a directory path","Default selections to concrete subdirectories"],"tags":["validation","filesystem","path"],"backgroundTag":"invalid-argument-value","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"}