apple/pkl · error · RuntimeException

Failed to parse transitive imports from

Error message

Failed to parse transitive imports from ${outputFile}

What it means

parseTransitiveFiles runs the Pkl analyzer/import graph over a dependency output file to discover transitive imports. If any exception occurs while parsing the import graph or processing its resolved imports (filtering file-scheme URIs into Files), it is rethrown as this RuntimeException naming the output file.

Solutions

  1. Clean and regenerate the output file (gradle clean or delete the Pkl dependency cache) and rerun the task
  2. Verify all transitively imported Pkl modules exist and evaluate without errors (run pkl eval manually)
  3. Check Pkl plugin and CLI version compatibility after upgrades
  4. Inspect the cause (wrapped exception) to identify the underlying parse/IO failure

Example fix

// before
// stale cached output reused
// after
./gradlew clean pklProject --rerun-tasks
Defensive patterns

Strategy: try-catch

Validate before calling

// before running transitive import resolution:
if (!outputFile.getAsFile().exists()) throw new GradleException("Dependency output missing: " + outputFile.getAsFile() + "; run the generating task first");

Try / catch

try {
  files = PluginUtils.parseTransitiveFiles(provider, fn);
} catch (RuntimeException e) {
  logger.warn("Transitive import parse failed: {}", e.getMessage());
  files = List.of(); // or fail fast depending on build strictness
}

Prevention

When it happens

Trigger: Calling a task that resolves transitive imports (e.g. PklDependencyTask) when the dependency output file is missing, corrupt, or produced by an incompatible Pkl version, or when the import graph computation throws internally.

Common situations: Stale or partially written dependency cache after an interrupted build, Pkl version upgrades changing the output file format, deleted project source files listed in the import graph, or configuration errors inside imported modules.

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/b4dff969f5930bce. Report an issue: GitHub.

Appendix: source

Thrown at pkl-gradle/src/main/java/org/pkl/gradle/utils/PluginUtils.java:164

   * assumes JSON format and should only be called for those tasks.
   *
   * @param outputFile the output file produced by the analyze imports task
   * @return the list of file-based transitive import paths
   */
  public static List<File> parseTransitiveFiles(RegularFile outputFile) {
    if (!outputFile.getAsFile().exists()) {
      return Collections.emptyList();
    }
    try {
      var contents = Files.readString(outputFile.getAsFile().toPath());
      var importGraph = ImportGraph.parseFromJson(contents);
      var imports = importGraph.resolvedImports().values();
      return imports.stream()
          .filter(it -> it.getScheme().equalsIgnoreCase("file"))
          .map(File::new)
          .toList();
    } catch (Exception e) {
      throw new RuntimeException(
          "Failed to parse transitive imports from " + outputFile.getAsFile(), e);
    }
  }

  /**
   * Equivalent to {@code provider.map(it -> f.apply(it)).getOrNull()}.
   *
   * <p>This function is necessary because in some cases doing {@code
   * someProvider.map(...).getOrNull()} may trigger validation errors inside Gradle, when {@code
   * someProvider} is derived from a property.
   */
  public static <T, U> @Nullable U mapAndGetOrNull(Provider<T> provider, Function<T, U> f) {
    @Nullable T value = provider.getOrNull();
    return value == null ? null : f.apply(value);
  }

  public static TestReporter toTestReporter(Provider<String> input) {
    var inputStr = input.getOrNull();

View on GitHub (pinned to f3efcbfc9b)