{"record":{"id":"4efa7165edeab54f","repo":"oracle/graal","slug":"error-deleting-s-this-is-most-likely-due-to-a-co","errorCode":null,"errorMessage":"Error deleting %s. This is most likely due to a compilation on another thread holding an open handle to a file within this directory. Please delete the directory manually once the VM exits.","messagePattern":"Error deleting (.+?)\\. This is most likely due to a compilation on another thread holding an open handle to a file within this directory\\. Please delete the directory manually once the VM exits\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/StandardPathUtilitiesProvider.java","lineNumber":221,"sourceCode":"                });\n                // Keep this in sync with the catch_files in ci/common.jsonnet\n                TTY.println(DIAGNOSTIC_OUTPUT_DIRECTORY_MESSAGE_FORMAT, zipFile);\n                return zipFile.getAbsolutePath();\n            } catch (IOException e) {\n                toDelete.clear();\n                throw new IOException(\"Error archiving \" + dir + \". This directory will not be deleted and must be manually removed.\", e);\n            } finally {\n                if (!toDelete.isEmpty()) {\n                    IOException lastDeletionError = null;\n                    for (Path p : toDelete) {\n                        try {\n                            Files.delete(p);\n                        } catch (IOException e) {\n                            lastDeletionError = e;\n                        }\n                    }\n                    if (lastDeletionError != null) {\n                        throw new IOException(\"Error deleting \" + dir + \". This is most likely due to a compilation on \" +\n                                        \"another thread holding an open handle to a file within this directory. \" +\n                                        \"Please delete the directory manually once the VM exits.\", lastDeletionError);\n                    }\n                }\n            }\n        }\n        return null;\n    }\n}\n","sourceCodeStart":203,"sourceCodeEnd":231,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/StandardPathUtilitiesProvider.java#L203-L231","documentation":"After a diagnostic dump directory is archived, StandardPathUtilitiesProvider deletes the original files; each delete failure is collected and, if any remain, this IOException is thrown with the last error chained. It explains the typical cause: another compilation thread still holds an open handle to a file inside the directory, so deletion is deferred to the user after VM exit.","triggerScenarios":"Two compilations dumping into the same output directory concurrently — one thread's channel/writer is still open when the other thread's cleanup walks and deletes the tree. On Unix an open handle does not usually block unlink, so this is most characteristic of Windows semantics or NFS/overlay filesystems; files locked by external tools (AV scanners, editors) produce it too.","commonSituations":"Windows development machines running multi-threaded Graal compilations with dumping enabled; antivirus/indexers briefly locking freshly written dump files; network filesystems with mandatory locking. Benign in the sense that the archive succeeded — only cleanup failed.","solutions":["As the message says: delete the directory manually once the VM exits — the archive zip referenced in the preceding log line already contains the data.","Give each compilation/run its own -Dgraal.DumpPath subdirectory so cleanups never overlap.","Exclude dump directories from antivirus/on-access scanners, or move DumpPath off network/locked filesystems.","Periodically purge old dump roots from CI machines to keep stray directories from accumulating."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    provider.cleanupAndArchiveOutputs(dir);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Error deleting\")) {\n        // archive already succeeded; directory removal is cosmetic — handle after VM exit\n        LOG.info(\"{}\", e.getMessage());\n    } else {\n        throw e;\n    }\n}","preventionTips":["On Windows, exclude dump directories from antivirus scanning and expect deferred deletion when compilations overlap.","Add an end-of-run sweep that deletes leftover dump directories after the JVM exits."],"tags":["diagnostic-output","file-deletion","concurrency","io","windows"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}