{"record":{"id":"3c563e48f4053a2d","repo":"bazelbuild/bazel","slug":"could-not-write-exit-file-at-file","errorCode":null,"errorMessage":"Could not write exit file at ${file}","messagePattern":"Could not write exit file at (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java","lineNumber":127,"sourceCode":"      Runtime.getRuntime().removeShutdownHook(shutdownHook);\n    }\n  }\n\n  // Support for \"premature exit files\": Tests may write this to communicate\n  // to the runner in case of premature exit.\n  private static File getExitFile() {\n    String exitFile = System.getenv(\"TEST_PREMATURE_EXIT_FILE\");\n    return exitFile == null ? null : new File(exitFile);\n  }\n\n  private static void exitFileActive(@Nullable File file) {\n    if (file != null) {\n      try (FileOutputStream outputStream = new FileOutputStream(file, false)) {\n        // Overwrite file content.\n        outputStream.write(new byte[0]);\n        outputStream.close();\n      } catch (IOException e) {\n        throw new RuntimeException(\"Could not write exit file at \" + file, e);\n      }\n    }\n  }\n\n  private void exitFileInactive(@Nullable File file) {\n    if (file != null) {\n      try {\n        file.delete();\n      } catch (Throwable t) {\n        // Just print the stack trace, to avoid masking a real test failure.\n        t.printStackTrace(testRunnerOut);\n      }\n    }\n  }\n\n  // VisibleForTesting\n  TestSuiteModel getModel() {\n    return modelSupplier.get();","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java#L109-L145","documentation":"Thrown by JUnit4Runner.exitFileActive when the runner cannot truncate the file named by the TEST_PREMATURE_EXIT_FILE environment variable. Bazel's test harness sets this variable and expects the runner to empty the file at startup as a liveness signal; an IOException while opening or writing it is wrapped in a RuntimeException and aborts the run before any test executes.","triggerScenarios":"TEST_PREMATURE_EXIT_FILE points into a directory that does not exist, is read-only, or is not writable by the test user; the path is on a full disk or a filesystem that rejects the open (e.g. path names a directory).","commonSituations":"Running the JUnit4Runner manually with copied harness environment variables after the Bazel sandbox was cleaned up; docker containers where /tmp is mounted read-only; disk-full CI agents; SELinux denying writes to the sandbox path.","solutions":["If running the runner by hand, unset TEST_PREMATURE_EXIT_FILE (the code tolerates a null file).","Otherwise make the parent directory of the path exist and be writable by the test process (mkdir -p, chmod, correct volume mounts).","Free disk space / fix filesystem permissions on the sandbox tree and re-run bazel test.","When wrapping the runner, catch and report the IOException with the file path before it masks the real test result."],"exampleFix":"# before\nTEST_PREMATURE_EXIT_FILE=/nonexistent/dir/exit_file java ... JUnit4Runner ...\n# after (manual run)\nunset TEST_PREMATURE_EXIT_FILE\njava ... JUnit4Runner ...","handlingStrategy":"validation","validationCode":"// before running the runner in-process\nString exitFile = System.getenv(\"TEST_PREMATURE_EXIT_FILE\");\nif (exitFile != null) {\n  File f = new File(exitFile);\n  File dir = f.getParentFile();\n  if (dir != null && !(dir.isDirectory() && dir.canWrite())) {\n    throw new IllegalStateException(\"TEST_PREMATURE_EXIT_FILE dir not writable: \" + dir);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Unset TEST_PREMATURE_EXIT_FILE when invoking the runner outside bazel test.","Mount /tmp (or the sandbox tree) writable in containers that run Bazel tests.","Monitor disk space on CI agents; premature-exit writes fail early when full."],"tags":["junit","bazel","environment","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}