apple/pkl · error · VmException
externalReaderFailure
externalReaderFailure
Error message
externalReaderFailure
What it means
Thrown during import collection in the Pkl VM when an external reader process (used to read non-standard resources via the `read()` function or imports) fails. Pkl delegates reading of custom URL schemes to external reader executables; when that process throws ExternalReaderProcessException, this evalError wraps it. The cause carries the underlying reader failure detail.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/runtime/VmImportAnalyzer.java:154
} catch (URISyntaxException e) {
throw new VmExceptionBuilder()
.evalError("invalidModuleUri", entry.stringValue())
.withHint(e.getReason())
.withSourceSection(entry.sourceSection())
.build();
} catch (IOException e) {
throw new VmExceptionBuilder()
.evalError("ioErrorLoadingModule", entry.stringValue())
.withCause(e)
.withSourceSection(entry.sourceSection())
.build();
} catch (SecurityManagerException | PackageLoadError e) {
throw new VmExceptionBuilder()
.withSourceSection(entry.sourceSection())
.withCause(e)
.build();
} catch (ExternalReaderProcessException e) {
throw new VmExceptionBuilder()
.withSourceSection(entry.sourceSection())
.evalError("externalReaderFailure")
.withCause(e)
.build();
}
}
return result;
}
private record ImportEntry(URI moduleUri, ResolvedModuleKey resolvedModuleKey) {
private Import toImport() {
return new Import(resolvedModuleKey.getOriginal().getUri());
}
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Run the external reader command manually with the same URL to see the underlying error from the cause chain.
- Verify the reader executable is installed, on PATH, and has execute permissions.
- Fix the error inside the reader script itself (auth, path, network) — this error only surfaces the reader's failure.
- Check the ExternalReader registration in your CLI/code matches the URL scheme being imported.
Example fix
// before: reader registered for 'vault:' but vault CLI absent
new ExternalReader("vault", List.of("my-vault-reader"))
// after: ensure binary exists and fails gracefully
new ExternalReader("vault", List.of("/usr/local/bin/my-vault-reader")) Defensive patterns
Strategy: try-catch
Validate before calling
// before evaluation
String reader = "my-reader";
Process p = new ProcessBuilder(reader, "--version").start();
if (p.waitFor() != 0) throw new IllegalStateException("external reader " + reader + " not usable"); Try / catch
try {
result = evaluator.evaluateOutputText();
} catch (EvalException e) {
if (e.getMessage().contains("externalReaderFailure")) {
// inspect e.getCause() (ExternalReaderProcessException) for reader stderr
}
} Prevention
- Smoke-test the external reader binary in CI before running Pkl evaluations.
- Register readers with absolute executable paths, not bare names.
- Make reader scripts fail with clear stderr messages — they surface in the cause chain.
- Keep reader exit codes informative and log stderr on failure.
When it happens
Trigger: Evaluating a module whose imports (or `read()` calls) go through an external reader registered via ExternalReader, and the reader process exits non-zero, crashes, or reports an error while resolving the resource.
Common situations: Custom `fileenv:`/project reader scripts that are not executable or misconfigured; external reader binary not on PATH; reader script raising its own error (bad auth, missing file inside the reader); network failures inside a custom scheme reader.
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
- externalReaderFailure
- externalReaderFailure
- externalReaderFailure
- externalReaderFailure
- External reader process has already been closed.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/95767d6f34af3614.
Report an issue: GitHub.