apple/pkl · error · VmException

externalReaderFailure

externalReaderFailure

Error message

Failed to communicate with external reader process.

What it means

Pkl throws this when an external reader process — a custom reader registered via the CLI or API that supplies resources for a custom URI scheme — fails or communicates improperly. The original ExternalReaderProcessException is attached as the cause.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/unary/AbstractReadNode.java:80

    URI resolvedUri;
    try {
      resolvedUri = IoUtils.resolve(context.getSecurityManager(), moduleKey, parsedUri);
    } catch (FileNotFoundException e) {
      throw exceptionBuilder().evalError("cannotFindResource", resourceUri).build();
    } catch (URISyntaxException e) {
      throw exceptionBuilder()
          .evalError("invalidResourceUri", resourceUri)
          .withHint(e.getReason())
          .build();
    } catch (IOException e) {
      throw exceptionBuilder()
          .evalError("ioErrorReadingResource", resourceUri)
          .withHint(e.getMessage())
          .build();
    } catch (PackageLoadError | SecurityManagerException e) {
      throw exceptionBuilder().withCause(e).build();
    } catch (ExternalReaderProcessException e) {
      throw exceptionBuilder().evalError("externalReaderFailure").withCause(e).build();
    }

    if (!resolvedUri.isAbsolute()) {
      throw exceptionBuilder().evalError("cannotHaveRelativeResource", moduleKey.getUri()).build();
    }
    return resolvedUri;
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Inspect the cause chain for the external reader's own error output and fix the reader script/program.
  2. Verify the reader command declared in PklProject is executable and on PATH.
  3. Test the reader standalone to confirm it speaks the external reader protocol correctly.
  4. Upgrade or reinstall the tool/package that provides the external reader.

Example fix

// before (PklProject)
externalReader = "pkl-project-reader"  // not on PATH
// after
externalReader = "./bin/pkl-project-reader" // or install it
Defensive patterns

Strategy: try-catch

Validate before calling

// Before evaluation, verify the external reader runs:
//   ProcessBuilder(cmd).start() exits 0 and answers a protocol ping

Try / catch

try {
  result = evaluator.evaluateOutputSource(moduleSource);
} catch (PklException e) {
  if (e.getMessage() != null && e.getMessage().contains("external reader")) {
    // inspect cause, repair/restart reader, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `read()` on a scheme handled by an external reader (e.g. custom project readers) when the reader process crashes, emits malformed output, or exits unexpectedly.

Common situations: A custom external reader script with a bug; reader binary not executable or missing dependencies; reader times out; reader emits output not matching the external reader protocol.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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