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

  1. Run the external reader command manually with the same URL to see the underlying error from the cause chain.
  2. Verify the reader executable is installed, on PATH, and has execute permissions.
  3. Fix the error inside the reader script itself (auth, path, network) — this error only surfaces the reader's failure.
  4. 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

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


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