{"record":{"id":"9373c15f904a3aef","repo":"oracle/graal","slug":"parent-directory-doesn-t-exist-for-resourcepath","errorCode":null,"errorMessage":"parent directory doesn't exist for: {resourcePath}","messagePattern":"parent directory doesn't exist for: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso.hotswap/src/com/oracle/truffle/espresso/hotswap/ServiceWatcher.java","lineNumber":279,"sourceCode":"\n        // Map all active file watches with the set of paths for which the watch was\n        // registered to enable us to cancel watches when deleted folders are recreated.\n        // A counter on each path reason is kept for managing when we should cancel the\n        // file system watch on the registered path.\n        private final Map<Path, Map<Path, Integer>> activeFileWatches = new HashMap<>();\n\n        private WatcherThread() throws IOException {\n            super(\"hotswap-watcher-1\");\n            this.setDaemon(true);\n            this.watchService = FileSystems.getDefault().newWatchService();\n        }\n\n        public void addWatch(Path resourcePath, Runnable callback) throws IOException {\n            watchActions.put(resourcePath, new ServiceWatcher.State(calculateChecksum(resourcePath), callback));\n            // register watch on parent folder\n            Path dir = resourcePath.getParent();\n            if (dir == null) {\n                throw new IOException(\"parent directory doesn't exist for: \" + resourcePath);\n            }\n            registerFileSystemWatch(dir, resourcePath, ALL_WATCH_KINDS);\n        }\n\n        private void addWatchedDeletedFolder(Path path, Path leaf) {\n            Set<Path> set = watchedForDeletion.get(path);\n            if (set == null) {\n                set = new HashSet<>();\n                watchedForDeletion.put(path, set);\n            }\n            set.add(leaf);\n        }\n\n        private void addWatchedCreatedFolder(Path path, Path leaf) {\n            Set<Path> set = watchedForCreation.get(path);\n            if (set == null) {\n                set = new HashSet<>();\n                watchedForCreation.put(path, set);","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso.hotswap/src/com/oracle/truffle/espresso/hotswap/ServiceWatcher.java#L261-L297","documentation":"WatcherThread.addWatch registers a filesystem watch for a file path but must watch its parent directory. Path.getParent() returns null when the path has no parent (a root like '/' or a relative single name), which the code reports as IOException('parent directory doesn't exist for: ...').","triggerScenarios":"addWatch called with a root path ('/') or a bare relative filename with no directory component while the service watcher tries to register the containing folder.","commonSituations":"Resource URLs resolving to filesystem roots; mis-resolved URL.toURI() producing root-level paths; relative paths used from an unexpected working directory.","solutions":["Pass an absolute, non-root file path (a real file inside a directory) to addWatch.","Normalize with path.toAbsolutePath().normalize() before registering.","Guard: if path.getParent() == null, skip or report instead of registering."],"exampleFix":"// before\nwatcher.addWatch(Path.of(\"services.cfg\")); // relative, parent may be null\n\n// after\nPath p = Path.of(\"services.cfg\").toAbsolutePath().normalize();\nif (p.getParent() != null) {\n    watcher.addWatch(p);\n}","handlingStrategy":"validation","validationCode":"Path abs = path.toAbsolutePath().normalize();\nif (abs.getParent() != null) {\n    watcher.addWatch(abs, callback);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass absolute, non-root file paths to filesystem watchers.","Normalize paths derived from URLs before use."],"tags":["espresso","hotswap","filesystem","paths"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}