OpenAPITools/openapi-generator · error · IllegalArgumentException

Choose between Spring Boot 3 and Spring Boot 4

Error message

Choose between Spring Boot 3 and Spring Boot 4

What it means

kotlin-spring has mutually exclusive Spring Boot major-version switches. If both useSpringBoot3 and useSpringBoot4 resolve to true after option processing, processOpts() throws 'Choose between Spring Boot 3 and Spring Boot 4' (KotlinSpringServerCodegen.java:847). Each flag is only defaulted when not set, so this fires only when both are explicitly true in the same invocation.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java:847

        writePropertyBack(AUTO_X_SPRING_PAGINATED, autoXSpringPaginated);
        if (additionalProperties.containsKey(GENERATE_SORT_VALIDATION) && library.equals(SPRING_BOOT)) {
            this.setGenerateSortValidation(convertPropertyToBoolean(GENERATE_SORT_VALIDATION));
        }
        writePropertyBack(GENERATE_SORT_VALIDATION, generateSortValidation);
        if (additionalProperties.containsKey(GENERATE_PAGEABLE_CONSTRAINT_VALIDATION) && library.equals(SPRING_BOOT)) {
            this.setGeneratePageableConstraintValidation(convertPropertyToBoolean(GENERATE_PAGEABLE_CONSTRAINT_VALIDATION));
        }
        writePropertyBack(GENERATE_PAGEABLE_CONSTRAINT_VALIDATION, generatePageableConstraintValidation);
        if (additionalProperties.containsKey(SUBSTITUTE_GENERIC_PAGED_MODEL)) {
            this.setSubstituteGenericPagedModel(convertPropertyToBoolean(SUBSTITUTE_GENERIC_PAGED_MODEL));
        }
        writePropertyBack(SUBSTITUTE_GENERIC_PAGED_MODEL, substituteGenericPagedModel);
        if (additionalProperties.containsKey(CodegenConstants.USE_ENUM_VALUE_INTERFACE)) {
            this.setUseEnumValueInterface(convertPropertyToBoolean(CodegenConstants.USE_ENUM_VALUE_INTERFACE));
        }
        writePropertyBack(CodegenConstants.USE_ENUM_VALUE_INTERFACE, useEnumValueInterface);
        if (isUseSpringBoot3() && isUseSpringBoot4()) {
            throw new IllegalArgumentException("Choose between Spring Boot 3 and Spring Boot 4");
        }

        if (isUseJackson3() && !isUseSpringBoot4()) {
            throw new IllegalArgumentException("useJackson3 is only available with Spring Boot >= 4");
        }

        if (additionalProperties.containsKey(CodegenConstants.OPENAPI_NULLABLE)) {
            this.setOpenApiNullable(convertPropertyToBoolean(CodegenConstants.OPENAPI_NULLABLE));
        }
        writePropertyBack(CodegenConstants.OPENAPI_NULLABLE, openApiNullable);

        if (isUseSpringBoot3() || isUseSpringBoot4()) {
            if (AnnotationLibrary.SWAGGER1.equals(getAnnotationLibrary())) {
                throw new IllegalArgumentException(AnnotationLibrary.SWAGGER1.getPropertyName() + " is not supported with Spring Boot > 3.x");
            }
            useJakartaEe = true;
            additionalProperties.put(USE_JAKARTA_EE, useJakartaEe);
            applyJakartaPackage();

View on GitHub (pinned to fcec517be3)

Solutions

  1. Keep exactly one version flag: remove `useSpringBoot3=true` and keep `useSpringBoot4=true` (or vice versa).
  2. In shared build logic, make the Boot version a single variable that expands to one flag instead of two independent booleans.
  3. After the fix, verify only one of useSpringBoot3/useSpringBoot4 appears in the generated pom/build files.

Example fix

# before
openapi-generator-cli generate -g kotlin-spring -i api.yaml \
  --additional-properties useSpringBoot3=true,useSpringBoot4=true
# after
openapi-generator-cli generate -g kotlin-spring -i api.yaml \
  --additional-properties useSpringBoot4=true
Defensive patterns

Strategy: validation

Validate before calling

boolean sb3 = Boolean.parseBoolean(String.valueOf(opts.getOrDefault("useSpringBoot3", "false")));
boolean sb4 = Boolean.parseBoolean(String.valueOf(opts.getOrDefault("useSpringBoot4", "false")));
if (sb3 && sb4) {
    throw new IllegalArgumentException("Set only one of useSpringBoot3 / useSpringBoot4");
}

Try / catch

try {
    new DefaultGenerator().opts(clientOptInput).generate();
} catch (IllegalArgumentException e) {
    throw new BuildException("Invalid kotlin-spring options: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Passing `--additional-properties useSpringBoot3=true,useSpringBoot4=true` in one command, or setting both <useSpringBoot3>true</useSpringBoot3> and <useSpringBoot4>true</useSpringBoot4> in the Maven/Gradle plugin configOptions block.

Common situations: Appending version flags during a Boot 3 → Boot 4 migration without removing the old one; build scripts that concatenate a base options map with override options; documentation examples updated to Boot 4 while the user's script still adds useSpringBoot3.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/192dbe1d7929c2d6. Report an issue: GitHub.