OpenAPITools/openapi-generator · error · IllegalArgumentException

Flags 'useSwaggerV3Annotations' and 'useMicroProfileOpenAPIA

Error message

Flags 'useSwaggerV3Annotations' and 'useMicroProfileOpenAPIAnnotations' are mutually exclusive. Please enable only one.

What it means

Thrown by JavaJAXRSSpecServerCodegen.processOpts when useSwaggerV3Annotations and useMicroProfileOpenAPIAnnotations are both true. The two annotation systems (Swagger Core v3 vs org.eclipse.microprofile.openapi) cover the same purpose — documenting JAX-RS endpoints — and the templates pick one emitter, so combining them produces duplicated/conflicting annotations. Unlike the v2/v3 pair, there is no auto-preference: both truthy means an error.

Source

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

            useSwaggerAnnotations = false;
        } else {
            convertPropertyToBooleanAndWriteBack(USE_SWAGGER_ANNOTATIONS, value -> useSwaggerAnnotations = value);
        }
        // Swagger v3 can be used regardless of library
        convertPropertyToBooleanAndWriteBack(USE_SWAGGER_V3_ANNOTATIONS, value -> useSwaggerV3Annotations = value);
        // prefer v3 when requested
        if (useSwaggerV3Annotations) {
            useSwaggerAnnotations = false;
        }
        if (KUMULUZEE_LIBRARY.equals(library)) {
            super.setSourceFolder("src/main/java");
        }

        if (useSwaggerAnnotations && useSwaggerV3Annotations) {
            throw new IllegalArgumentException("Flags 'useSwaggerAnnotations' (v2) and 'useSwaggerV3Annotations' (v3) are mutually exclusive. Please enable only one.");
        }
        if (useSwaggerV3Annotations && useMicroProfileOpenAPIAnnotations) {
            throw new IllegalArgumentException("Flags 'useSwaggerV3Annotations' and 'useMicroProfileOpenAPIAnnotations' are mutually exclusive. Please enable only one.");
        }

        if (QUARKUS_LIBRARY.equals(library)) {
            convertPropertyToBooleanAndWriteBack(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, value -> useMicroProfileOpenAPIAnnotations = value);
        }

        if (QUARKUS_LIBRARY.equals(library)) {
            convertPropertyToBooleanAndWriteBack(USE_MUTINY, value -> useMutiny = value);
        }

        convertPropertyToBooleanAndWriteBack(GENERATE_JSON_CREATOR, this::setGenerateJsonCreator);
        convertPropertyToBooleanAndWriteBack(USE_ENUM_CASE_INSENSITIVE, this::setUseEnumCaseInsensitive);
        convertPropertyToBooleanAndWriteBack(USE_SEALED, this::setUseSealed);

        if (additionalProperties.containsKey(OPEN_API_SPEC_FILE_LOCATION)) {
            openApiSpecFileLocation = additionalProperties.get(OPEN_API_SPEC_FILE_LOCATION).toString();
        } else if (QUARKUS_LIBRARY.equals(library) || THORNTAIL_LIBRARY.equals(library) || HELIDON_LIBRARY.equals(library) || KUMULUZEE_LIBRARY.equals(library)) {
            openApiSpecFileLocation = "src/main/resources/META-INF/openapi.yaml";

View on GitHub (pinned to fcec517be3)

Solutions

  1. For Quarkus, prefer useMicroProfileOpenAPIAnnotations=true (native to the platform) and remove useSwaggerV3Annotations
  2. For plain JAX-RS/Swagger tooling, keep useSwaggerV3Annotations=true and remove the MicroProfile flag
  3. Check the effective merged options once (CLI flags + --config + configOptions) and delete the redundant key
  4. Document a single annotation standard per generator in your team's config-as-code repo

Example fix

# before
openapi-generator-cli generate -g jaxrs-jersey -i api.yaml --library quarkus \
  --additional-properties useSwaggerV3Annotations=true,useMicroProfileOpenAPIAnnotations=true

# after
openapi-generator-cli generate -g jaxrs-jersey -i api.yaml --library quarkus \
  --additional-properties useMicroProfileOpenAPIAnnotations=true
Defensive patterns

Strategy: validation

Validate before calling

boolean v3 = Boolean.parseBoolean(String.valueOf(opts.getOrDefault("useSwaggerV3Annotations", "false")));
boolean mp = Boolean.parseBoolean(String.valueOf(opts.getOrDefault("useMicroProfileOpenAPIAnnotations", "false")));
if (v3 && mp) {
    throw new IllegalArgumentException("useSwaggerV3Annotations and useMicroProfileOpenAPIAnnotations are mutually exclusive");
}

Try / catch

try {
    generator.generate();
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("useMicroProfileOpenAPIAnnotations")) {
        throw new ConfigException("Pick one annotation system: Swagger v3 or MicroProfile OpenAPI", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing --additional-properties useSwaggerV3Annotations=true,useMicroProfileOpenAPIAnnotations=true to -g jaxrs-jersey (especially with --library quarkus, where the MicroProfile flag is explicitly read via convertPropertyToBooleanAndWriteBack). Also via config files merged from a Quarkus template that already enables MicroProfile annotations.

Common situations: Quarkus projects: Quarkus natively consumes MP OpenAPI annotations, but devs add swagger-v3 annotations for swagger-codegen tooling and enable both. Config inheritance from a shared base preset plus per-service overrides re-enables the deleted flag.

Related errors


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