apple/pkl · error · GradleException
Could not find a source set for code generator
Error message
Could not find a source set for code generator '${name}'. Either apply a JVM plugin (e.g. 'java') or set the sourceSet property explicitly. What it means
When configuring code-generation tasks, each CodeGen spec must resolve to a Gradle SourceSet. If the spec's sourceSet property is unset and no JVM plugin (java/kotlin) has been applied to the project, there is no default source set to resolve, and the plugin throws GradleException. It exists to tell users they must either apply a JVM plugin or set sourceSet explicitly.
Solutions
- Apply a JVM plugin to the same project: add `java` (or `kotlin`) to its plugins block.
- Set the source set explicitly in the codegen block: `sourceSet = sourceSets.main` (or `sourceSets.test`).
- Check you applied the codegen config in the correct subproject, not the root.
- If the module is intentionally non-JVM, remove the codegen block and invoke codegen via the CLI instead.
Example fix
// before (build.gradle.kts)
pkl { codegen { generators { register("pklGen") { ... } } } }
// after
plugins { `java` }
pkl { codegen { generators { register("pklGen") { sourceSet = sourceSets.main; ... } } } } Defensive patterns
Strategy: validation
Validate before calling
val codegen = project.extensions.getByType<PklExtension>().codegen
codegen.generators.forEach { require(it.sourceSet.isPresent || project.plugins.hasPlugin(JavaPlugin::class.java)) { "Apply 'java' or set sourceSet for generator ${it.name}" } } Type guard
fun Project.hasDefaultSourceSet() = plugins.hasPlugin(JavaPlugin::class.java) || plugins.hasPlugin(KotlinPluginWrapper::class.java)
Try / catch
try { pkl.configure(...) } catch (GradleException e) { if (e.message?.contains('source set')) logger.error('Apply java/kotlin plugin or set sourceSet on generator ' + name); throw e } Prevention
- Apply java/kotlin plugin in every subproject using pkl codegen
- Always set sourceSet explicitly rather than relying on defaults
- Verify with a failing-fast configuration check in CI
- Keep codegen blocks only in JVM modules
When it happens
Trigger: Applying pkl-codegen in a project (or subproject) without the `java` or `kotlin` plugin, leaving codegen { generator { ... } } blocks without a sourceSet = ... assignment; running configureJavaCodeGenTasks/configureKotlinCodeGenTasks over such a spec.
Common situations: Pkl codegen added to a non-JVM module like a pure Pkl or docs subproject; a multi-project build where the JVM plugin is applied at the root but not in the subproject containing the codegen block; migrating from an older plugin version with different defaults.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Failed to parse Pkl module file path
- Invalid test reporter
- No source modules specified.
- Unsupported value of type
- Annotation `$fqn` is not a valid Java class. The name of…
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/42ff4cb9f01a4423.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-gradle/src/main/java/org/pkl/gradle/PklPlugin.java:435
.getSourceDirectories()
.filter(
f ->
!f.getAbsolutePath()
.startsWith(
specOutputDir.getAsFile().getAbsolutePath()))
.getFiles()));
}
private void configureCodeGenSpecSourceDirectories(
Project project,
CodeGenSpec spec,
String languageName,
Function<? super SourceSet, ? extends Optional<SourceDirectorySet>>
extractSourceDirectorySet) {
var task = project.getTasks().named(spec.getName(), CodeGenTask.class);
var sourceSet = spec.getSourceSet().getOrNull();
if (sourceSet == null) {
throw new GradleException(
"Could not find a source set for code generator '"
+ spec.getName()
+ "'. Either apply a JVM plugin (e.g. 'java') or set the sourceSet property explicitly.");
}
extractSourceDirectorySet
.apply(sourceSet)
.ifPresentOrElse(
dirSet -> dirSet.srcDir(task.flatMap(t -> t.getOutputDir().dir(languageName))),
() ->
project
.getLogger()
.debug(
"Source directory set for language {} is not available, "
+ "will not add task {} as its dependency",
languageName,
task.getName()));
sourceSet.getResources().srcDir(task.flatMap(t -> t.getOutputDir().dir("resources")));
}View on GitHub (pinned to f3efcbfc9b)