{"record":{"id":"565cefc730b522a5","repo":"apple/pkl","slug":"externalreaderfailure-565cef","errorCode":"externalReaderFailure","errorMessage":"Failed to communicate with external reader process.","messagePattern":"Failed to communicate with external reader process\\.","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/expression/unary/AbstractReadNode.java","lineNumber":80,"sourceCode":"    URI resolvedUri;\n    try {\n      resolvedUri = IoUtils.resolve(context.getSecurityManager(), moduleKey, parsedUri);\n    } catch (FileNotFoundException e) {\n      throw exceptionBuilder().evalError(\"cannotFindResource\", resourceUri).build();\n    } catch (URISyntaxException e) {\n      throw exceptionBuilder()\n          .evalError(\"invalidResourceUri\", resourceUri)\n          .withHint(e.getReason())\n          .build();\n    } catch (IOException e) {\n      throw exceptionBuilder()\n          .evalError(\"ioErrorReadingResource\", resourceUri)\n          .withHint(e.getMessage())\n          .build();\n    } catch (PackageLoadError | SecurityManagerException e) {\n      throw exceptionBuilder().withCause(e).build();\n    } catch (ExternalReaderProcessException e) {\n      throw exceptionBuilder().evalError(\"externalReaderFailure\").withCause(e).build();\n    }\n\n    if (!resolvedUri.isAbsolute()) {\n      throw exceptionBuilder().evalError(\"cannotHaveRelativeResource\", moduleKey.getUri()).build();\n    }\n    return resolvedUri;\n  }\n}\n","sourceCodeStart":62,"sourceCodeEnd":89,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/expression/unary/AbstractReadNode.java#L62-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the cause chain for the external reader's own error output and fix the reader script/program.","Verify the reader command declared in PklProject is executable and on PATH.","Test the reader standalone to confirm it speaks the external reader protocol correctly.","Upgrade or reinstall the tool/package that provides the external reader."],"exampleFix":"// before (PklProject)\nexternalReader = \"pkl-project-reader\"  // not on PATH\n// after\nexternalReader = \"./bin/pkl-project-reader\" // or install it","handlingStrategy":"try-catch","validationCode":"// Before evaluation, verify the external reader runs:\n//   ProcessBuilder(cmd).start() exits 0 and answers a protocol ping","typeGuard":null,"tryCatchPattern":"try {\n  result = evaluator.evaluateOutputSource(moduleSource);\n} catch (PklException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"external reader\")) {\n    // inspect cause, repair/restart reader, then retry\n  } else throw e;\n}","preventionTips":["Version-control and test your external reader scripts; run them standalone in CI.","Use absolute paths to the reader binary in PklProject to avoid PATH issues.","Keep reader output strictly conformant to the external reader protocol."],"tags":["external-reader","process","resource","pkl"],"backgroundTag":"http-request-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}