{"record":{"id":"ba1855df396554f1","repo":"java-native-access/jna","slug":"klib-getlasterror","errorCode":"klib.GetLastError()","errorMessage":"Unable to open <file> (<GetLastError>)","messagePattern":"Unable to open <file> \\(<GetLastError>\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java","lineNumber":193,"sourceCode":"        }\n        while (dir != null && !dir.exists()) {\n            recursive = true;\n            dir = dir.getParentFile();\n        }\n        if (dir == null) {\n            throw new FileNotFoundException(\"No ancestor found for \" + file);\n        }\n        Kernel32 klib = Kernel32.INSTANCE;\n        int mask = WinNT.FILE_SHARE_READ\n            | WinNT.FILE_SHARE_WRITE | WinNT.FILE_SHARE_DELETE;\n        int flags = WinNT.FILE_FLAG_BACKUP_SEMANTICS\n            | WinNT.FILE_FLAG_OVERLAPPED;\n        HANDLE handle = klib.CreateFile(file.getAbsolutePath(),\n                WinNT.FILE_LIST_DIRECTORY,\n                mask, null, WinNT.OPEN_EXISTING,\n                flags, null);\n        if (WinBase.INVALID_HANDLE_VALUE.equals(handle)) {\n            throw new IOException(\"Unable to open \" + file + \" (\"\n                                  + klib.GetLastError() + \")\");\n        }\n        int notifyMask = convertMask(eventMask);\n        FileInfo finfo = new FileInfo(file, handle, notifyMask, recursive);\n        fileMap.put(file, finfo);\n        handleMap.put(handle, finfo);\n        // Existing port is returned\n        port = klib.CreateIoCompletionPort(handle, port, handle.getPointer(), 0);\n        if (WinBase.INVALID_HANDLE_VALUE.equals(port)) {\n            throw new IOException(\"Unable to create/use I/O Completion port \"\n                    + \"for \" + file + \" (\"\n                    + klib.GetLastError() + \")\");\n        }\n        // TODO: use FileIOCompletionRoutine callback method instead of a\n        // dedicated thread\n        if (!klib.ReadDirectoryChangesW(handle, finfo.info, finfo.info.size(),\n                                        recursive, notifyMask, finfo.infoLength,\n                                        finfo.overlapped, null)) {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java#L175-L211","documentation":"W32FileMonitor.watch opens the directory with CreateFile (FILE_LIST_DIRECTORY) to monitor changes. If CreateFile returns INVALID_HANDLE_VALUE, an IOException containing the GetLastError code is thrown, meaning the directory could not be opened for change notification.","triggerScenarios":"CreateFile fails when opening the watch target: directory does not exist, access denied (ERROR_ACCESS_DENIED=5), invalid path characters, or the path maps to a file rather than a directory on an OS/handle combination that disallows it.","commonSituations":"Watching a directory the process lacks read permission for; race where the folder is deleted between the ancestor check and CreateFile; watching a mapped drive that is offline.","solutions":["Check File.exists() and directory readability immediately before addWatch","Run the application under an account with sufficient permissions for the target directory","Handle the IOException and retry with a corrected/validated path","Avoid watching network/removable paths that may be unavailable"],"exampleFix":"// before\nmonitor.addWatch(dir, listener);\n// after\nif (dir.exists() && dir.isDirectory()) {\n    try {\n        monitor.addWatch(dir, listener);\n    } catch (IOException e) {\n        // handle ERROR_ACCESS_DENIED etc.\n    }\n}","handlingStrategy":"validation","validationCode":"if (!file.exists() || !file.isDirectory() || !file.canRead()) {\n    throw new IllegalArgumentException(\"Cannot watch: \" + file);\n}","typeGuard":null,"tryCatchPattern":"try {\n    monitor.addWatch(dir, listener);\n} catch (IOException e) {\n    // GetLastError code is embedded in the message; handle access-denied explicitly\n}","preventionTips":["Ensure the process account has read access to the directory","Re-check existence right before addWatch (avoid TOCTOU races)","Avoid paths with invalid characters or unresolved symlinks"],"tags":["win32","file-monitoring","createfile"],"backgroundTag":"file-open-failed","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}