apple/pkl · error · VmException
ioErrorReadingTestOutputFile
ioErrorReadingTestOutputFile
Error message
ioErrorReadingTestOutputFile
What it means
`TestRunner.loadExampleOutputs` reads an expected or actual output Pcf file from disk to compare against fresh results. An IOException from `Files.readString` is wrapped as `ioErrorReadingTestOutputFile` naming the file. Since the file's existence is normally checked just before, this usually means a race, permissions problem, or invalid-encoding/IO issue.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/runtime/TestRunner.java:373
var builder = new StringBuilder();
new PcfRenderer(builder, " ", converter, false, true).renderDocument(outputFileContent);
try {
Files.writeString(outputFile, builder);
} catch (IOException e) {
throw new VmExceptionBuilder()
.evalError("ioErrorWritingTestOutputFile", outputFile)
.withCause(e)
.build();
}
}
private VmDynamic loadExampleOutputs(Path outputFile) {
// load file manually to prevent it from being cached (won't need it again)
String fileContent;
try {
fileContent = Files.readString(outputFile, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new VmExceptionBuilder()
.evalError("ioErrorReadingTestOutputFile", outputFile)
.withCause(e)
.build();
}
var module =
VmLanguage.get(null).loadModule(ModuleKeys.synthetic(outputFile.toUri(), fileContent));
var examples = (VmDynamic) VmUtils.readMemberOrNull(module, Identifier.EXAMPLES);
if (examples == null) {
throw new VmExceptionBuilder().evalError("invalidOutputFileStructure", outputFile).build();
}
return examples;
}
private static String renderAsPcf(Object pklValue) {
var builder = new StringBuilder();
new PcfRenderer(builder, " ", converter, false, false).renderValue(pklValue);
if (pklValue instanceof VmObject) {
builder.insert(0, "new ");View on GitHub (pinned to f3efcbfc9b)
Solutions
- Verify the output file still exists and is readable (ls -l, check ownership/permissions).
- Stop concurrent processes that delete or regenerate `*-pcf` files during the run.
- Regenerate the expected file with `pkl test --overwrite` (after ensuring write access).
- Avoid running tests against files on flaky network mounts; use a local copy.
Example fix
// before: expected file owned by root, test run as non-root // after sudo chown "$(whoami)" MyTest-expected.pcf && chmod u+rw MyTest-expected.pcf pkl test MyTest.pkl
Defensive patterns
Strategy: validation
Validate before calling
// verify output files are readable before testing
Path expected = moduleFile.resolveSibling(moduleFile.getFileName() + "-expected.pcf");
if (Files.exists(expected) && !Files.isReadable(expected)) {
throw new IllegalStateException("Unreadable: " + expected);
} Try / catch
catch (EvalError e) { /* withCause IOException: fix permissions/regenerate expected file */ } Prevention
- Avoid generating expected-output files as root; use consistent ownership.
- Don't run concurrent jobs that clean or regenerate *-pcf files.
- Prefer local filesystems over flaky network mounts for test runs.
When it happens
Trigger: Reading `X-expected.pcf` or `X-actual.pcf` fails: file deleted between the existence check and the read, unreadable permissions, locked file, or charset/IO error.
Common situations: Parallel processes cleaning generated files mid-test; expected-output file unreadable by the current user (wrong ownership after sudo-generated files); filesystem hiccup in containers or network mounts.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- ioErrorWritingTestOutputFile
- cannotEvaluateNonFileBasedTestModule
- invalidOutputFileStructure
- ioErrorLoadingModule
- ioErrorLoadingModule
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/7b6b272f5d78bd6f.
Report an issue: GitHub.