apple/pkl · error

commandArgumentsMultipleRepeated

commandArgumentsMultipleRepeated

Error message

commandArgumentsMultipleRepeated

What it means

collectOptions throws commandArgumentsMultipleRepeated when more than one positional @Argument property in the same options class is declared repeated (a list/vararg). At most one trailing repeated argument is allowed, since multiple variadic positionals make parsing ambiguous.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/CommandSpecParser.java:230

            argAnnotation = annotation;
          }
        }

        if (flagAnnotation != null && argAnnotation != null) {
          throw exceptionBuilder()
              .withSourceSection(prop.getHeaderSection())
              .evalError("commandOptionBothFlagAndArgument", prop.getName())
              .build();
        }

        if (argAnnotation != null) {
          var arg = collectArgument(prop, argAnnotation);
          opts.put(arg.name(), arg);
          if (arg.repeated()) {
            if (lastRepeatedArg == null) {
              lastRepeatedArg = arg;
            } else {
              throw exceptionBuilder()
                  .withSourceSection(optionsClass.getHeaderSection())
                  .evalError("commandArgumentsMultipleRepeated", lastRepeatedArg.name(), arg.name())
                  .build();
            }
          }
        } else {
          CommandSpec.Option flag;
          if (flagAnnotation == null
              || flagAnnotation.getVmClass() == CommandModule.getFlagClass()) {
            flag = collectFlag(prop, flagAnnotation);
          } else if (flagAnnotation.getVmClass() == CommandModule.getBooleanFlagClass()) {
            flag = collectBooleanFlag(prop, flagAnnotation);
          } else if (flagAnnotation.getVmClass() == CommandModule.getCountedFlagClass()) {
            flag = collectCountedFlag(prop, flagAnnotation);
          } else {
            throw PklBugException.unreachableCode();
          }
          opts.put(flag.name(), flag);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Keep only one repeated argument and remove/change the others to fixed positionals
  2. Merge the values into a single repeated argument and disambiguate at runtime
  3. Move the second variadic into a subcommand or a named option

Example fix

// before
@Argument files: List<String>
@Argument extra: List<String>
// after
@Argument files: List<String>
@Argument extra: String
Defensive patterns

Strategy: validation

Validate before calling

const repeatedArgs = argSpecs.filter(a => a.repeated);
if (repeatedArgs.length > 1) throw new Error(`only one repeated argument allowed: ${repeatedArgs.map(a => a.name)}`);

Prevention

When it happens

Trigger: Two or more @Argument properties whose collected spec has repeated() == true (e.g. typed as List/`*type`) within one options class.

Common situations: Wanting 'files...' plus 'extraFiles...' variadic positionals in one command; converting several optional arguments to lists without realizing only one variadic is permitted.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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