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
- Clean and regenerate the output file (gradle clean or delete the Pkl dependency cache) and rerun the task
- Verify all transitively imported Pkl modules exist and evaluate without errors (run pkl eval manually)
- Check Pkl plugin and CLI version compatibility after upgrades
- 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
- Run `gradle clean`/delete Pkl caches after plugin or Pkl version upgrades
- Keep the Pkl CLI/plugin versions aligned
- Ensure all imported modules exist and evaluate before dependency resolution
- Treat the wrapped cause as the real failure and fix it, not just the wrapper
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Plugin `org.pkl` requires Gradle
- Could not find a source set for code generator
- Failed to load class path resource `$resourceName`.
- Failed to parse Pkl module file path
- Failed to parse Pkl module file path
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)