apple/pkl · error · VmException

ioErrorWritingTestOutputFile

ioErrorWritingTestOutputFile

Error message

ioErrorWritingTestOutputFile

What it means

Before writing actual test output, `TestRunner.runExamples` deletes any stale `*-actual.pcf` file next to the test module. If `Files.deleteIfExists` throws an IOException (permissions, file locked, it is a directory), the error wraps that IOException as `ioErrorWritingTestOutputFile` naming the actual-output file path.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/TestRunner.java:158

    if (examples instanceof VmNull)
      return new TestSectionResults(TestSectionName.EXAMPLES, List.of());

    var moduleUri = info.getModuleKey().getUri();
    if (!moduleUri.getScheme().equalsIgnoreCase("file")) {
      throw new VmExceptionBuilder()
          .evalError("cannotEvaluateNonFileBasedTestModule", moduleUri)
          .build();
    }

    var examplesMapping = (VmMapping) examples;
    var moduleFile = Path.of(moduleUri);
    var expectedOutputFile = moduleFile.resolveSibling(moduleFile.getFileName() + "-expected.pcf");
    var actualOutputFile = moduleFile.resolveSibling(moduleFile.getFileName() + "-actual.pcf");

    try {
      Files.deleteIfExists(actualOutputFile);
    } catch (IOException e) {
      throw new VmExceptionBuilder()
          .evalError("ioErrorWritingTestOutputFile", actualOutputFile)
          .withCause(e)
          .build();
    }
    try {
      if (overwrite) {
        Files.deleteIfExists(expectedOutputFile);
      }
    } catch (IOException e) {
      throw new VmExceptionBuilder()
          .evalError("ioErrorWritingTestOutputFile", expectedOutputFile)
          .withCause(e)
          .build();
    }

    if (Files.exists(expectedOutputFile)) {
      return doRunAndValidateExamples(examplesMapping, expectedOutputFile, actualOutputFile);
    } else {

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Check and fix filesystem permissions on the directory containing the test module (chmod/writable mount).
  2. Close or stop any process holding `*-actual.pcf` open (editor, file watcher, sync client, antivirus scan).
  3. Verify no directory named `*-actual.pcf` exists at that path; remove it manually.
  4. Copy the test module into a writable directory (e.g. a temp dir) and run the test there.

Example fix

// before: running tests in a read-only mounted checkout
// after
chmod u+w /path/to/module-dir
ci: {
  chmod -R u+w "$CI_WORKSPACE" // ensure workspace is writable before `pkl test`
}
Defensive patterns

Strategy: validation

Validate before calling

// before running tests, ensure output path is writable
Path dir = moduleFile.getParent();
if (!Files.isWritable(dir)) {
    throw new IllegalStateException("Test dir not writable: " + dir);
}

Try / catch

catch (EvalError e) { /* inspect cause IOException; check dir permissions and file locks */ }

Prevention

When it happens

Trigger: The `X-actual.pcf` sibling of the tested module cannot be deleted: read-only directory, file locked by another process (editor/watcher/AV), path exists as a directory, or disk-level failure.

Common situations: Running tests in a read-only CI checkout; output file held open by an editor or sync tool (Dropbox/OneDrive); antivirus interference on Windows; the pkl file lives in a non-writable mounted volume.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/c7100fa587bf2a18. Report an issue: GitHub.