{"record":{"id":"c7100fa587bf2a18","repo":"apple/pkl","slug":"ioerrorwritingtestoutputfile","errorCode":"ioErrorWritingTestOutputFile","errorMessage":"ioErrorWritingTestOutputFile","messagePattern":"ioErrorWritingTestOutputFile","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/runtime/TestRunner.java","lineNumber":158,"sourceCode":"    if (examples instanceof VmNull)\n      return new TestSectionResults(TestSectionName.EXAMPLES, List.of());\n\n    var moduleUri = info.getModuleKey().getUri();\n    if (!moduleUri.getScheme().equalsIgnoreCase(\"file\")) {\n      throw new VmExceptionBuilder()\n          .evalError(\"cannotEvaluateNonFileBasedTestModule\", moduleUri)\n          .build();\n    }\n\n    var examplesMapping = (VmMapping) examples;\n    var moduleFile = Path.of(moduleUri);\n    var expectedOutputFile = moduleFile.resolveSibling(moduleFile.getFileName() + \"-expected.pcf\");\n    var actualOutputFile = moduleFile.resolveSibling(moduleFile.getFileName() + \"-actual.pcf\");\n\n    try {\n      Files.deleteIfExists(actualOutputFile);\n    } catch (IOException e) {\n      throw new VmExceptionBuilder()\n          .evalError(\"ioErrorWritingTestOutputFile\", actualOutputFile)\n          .withCause(e)\n          .build();\n    }\n    try {\n      if (overwrite) {\n        Files.deleteIfExists(expectedOutputFile);\n      }\n    } catch (IOException e) {\n      throw new VmExceptionBuilder()\n          .evalError(\"ioErrorWritingTestOutputFile\", expectedOutputFile)\n          .withCause(e)\n          .build();\n    }\n\n    if (Files.exists(expectedOutputFile)) {\n      return doRunAndValidateExamples(examplesMapping, expectedOutputFile, actualOutputFile);\n    } else {","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/runtime/TestRunner.java#L140-L176","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check and fix filesystem permissions on the directory containing the test module (chmod/writable mount).","Close or stop any process holding `*-actual.pcf` open (editor, file watcher, sync client, antivirus scan).","Verify no directory named `*-actual.pcf` exists at that path; remove it manually.","Copy the test module into a writable directory (e.g. a temp dir) and run the test there."],"exampleFix":"// before: running tests in a read-only mounted checkout\n// after\nchmod u+w /path/to/module-dir\nci: {\n  chmod -R u+w \"$CI_WORKSPACE\" // ensure workspace is writable before `pkl test`\n}","handlingStrategy":"validation","validationCode":"// before running tests, ensure output path is writable\nPath dir = moduleFile.getParent();\nif (!Files.isWritable(dir)) {\n    throw new IllegalStateException(\"Test dir not writable: \" + dir);\n}","typeGuard":null,"tryCatchPattern":"catch (EvalError e) { /* inspect cause IOException; check dir permissions and file locks */ }","preventionTips":["Run tests as a user with write access to the module directory.","Exclude *-actual.pcf / *-expected.pcf from editors, formatters, and sync tools.","Make CI checkouts writable (avoid read-only volume mounts for test jobs)."],"tags":["pkl","io","filesystem","testing"],"backgroundTag":"file-write-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}