apple/pkl · error · ExecutorException

Pkl module `%s` does not state which Pkl version it requires

Error message

Pkl module `%s` does not state which Pkl version it requires. (Available versions: %s)%nTo fix this problem, annotate the module's `amends`, `extends`, or `module` clause with `@ModuleInfo { minPklVersion = "x.y.z" }`.

What it means

After reading the module, detectRequestedPklVersion could not find a required Pkl version: the module has no @ModuleInfo { minPklVersion = ... } annotation on its amends/extends/module clause and extractMinPklVersion returned null. Because the embedded executor supports multiple Pkl distributions, it refuses to guess which version to use, listing the available versions instead.

Source

Thrown at pkl-executor/src/main/java/org/pkl/executor/EmbeddedExecutor.java:126

  private Version detectRequestedPklVersion(Path modulePath, ExecutorOptions options) {
    String sourceText;
    try {
      sourceText = Files.readString(modulePath, StandardCharsets.UTF_8);
    } catch (IOException e) {
      throw new ExecutorException(
          String.format("I/O error loading Pkl module `%s`.", toDisplayPath(modulePath, options)),
          e);
    }

    var version = extractMinPklVersion(sourceText);
    if (version != null) return version;

    var availableVersions =
        pklDistributions.stream()
            .map(it -> it.getVersion().toString())
            .collect(Collectors.joining(", "));

    throw new ExecutorException(
        String.format(
            "Pkl module `%s` does not state which Pkl version it requires. (Available versions: %s)%n"
                + "To fix this problem, annotate the module's `amends`, `extends`, or `module` clause with `@ModuleInfo { minPklVersion = \"x.y.z\" }`.",
            toDisplayPath(modulePath, options), availableVersions));
  }

  static @Nullable Version extractMinPklVersion(String sourceText) {
    var matcher = MODULE_INFO_PATTERN.matcher(sourceText);
    return matcher.find() ? Version.parse(matcher.group(1)) : null;
  }

  private PklDistribution findCompatibleDistribution(
      Path modulePath, Version requestedVersion, ExecutorOptions options) {
    var result =
        pklDistributions.stream()
            .filter(it -> it.getVersion().compareTo(requestedVersion) >= 0)
            .min(Comparator.comparing(PklDistribution::getVersion));

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Add @ModuleInfo { minPklVersion = "x.y.z" } to the module's amends, extends, or module clause
  2. Use the versions listed in the error message to pick a valid minPklVersion
  3. If your tooling generates modules, emit the annotation in the template

Example fix

// before
amends "pkl:base"

// after
@ModuleInfo { minPklVersion = "0.25.0" }
amends "pkl:base"
Defensive patterns

Strategy: validation

Validate before calling

String text = Files.readString(modulePath);
if (!text.contains("@ModuleInfo")) throw new IllegalArgumentException(modulePath + " missing @ModuleInfo minPklVersion");

Type guard

boolean declaresMinPklVersion(String src) { return src.contains("@ModuleInfo") && src.contains("minPklVersion"); }

Try / catch

try { executor.evaluatePath(p, options); } catch (ExecutorException e) { if (e.getMessage().contains("does not state which Pkl version")) { /* prompt to add annotation */ } throw e; }

Prevention

When it happens

Trigger: Evaluating a module whose header clause (amends/extends/module) lacks the @ModuleInfo { minPklVersion } annotation while multiple pklDistributions are configured, via evaluatePath.

Common situations: Older modules written before @ModuleInfo existed; modules copied/generated without the annotation; teams upgrading to a multi-version embedded executor setup.

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


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