OpenAPITools/openapi-generator · error · RuntimeException

Cannot merge specs that declare incompatible OpenAPI version

Error message

Cannot merge specs that declare incompatible OpenAPI versions %s. All specs must share the same major.minor version (e.g. all 3.0.x or all 3.1.x); mixing 3.0 and 3.1 is not supported because version-specific fields and semantics are not translated.

What it means

After well-formedness checks, resolveOutputVersion() compares every source's major.minor against the first spec's; any divergence throws with the distinct version list. Merging across major.minor lines (3.0.x with 3.1.x) is unsupported because version-specific fields and semantics are not translated. The merged output declares the highest patch version among sources once this check passes.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java:545

        if (versions.stream().anyMatch(Objects::isNull)) {
            throw new RuntimeException(
                    "Cannot merge specs where some declare an OpenAPI version and others do not. The 'openapi' "
                            + "field is required; every source spec must declare a version so compatibility can be verified.");
        }
        // Reject malformed versions before comparing, so a value like '3.x.3' cannot pass the
        // major.minor check by having its non-numeric segment normalized to zero.
        for (String version : versions) {
            if (!isWellFormedVersion(version)) {
                throw new RuntimeException(String.format(Locale.ROOT,
                        "Malformed OpenAPI version '%s' in a source spec. Expected exactly three numeric "
                                + "components (MAJOR.MINOR.PATCH) without leading zeroes, such as '3.0.3' or '3.1.0'.",
                        version));
            }
        }
        String firstMajorMinor = majorMinor(versions.get(0));
        for (String version : versions) {
            if (!majorMinor(version).equals(firstMajorMinor)) {
                throw new RuntimeException(String.format(Locale.ROOT,
                        "Cannot merge specs that declare incompatible OpenAPI versions %s. All specs must share "
                                + "the same major.minor version (e.g. all 3.0.x or all 3.1.x); mixing 3.0 and 3.1 "
                                + "is not supported because version-specific fields and semantics are not translated.",
                        versions.stream().distinct().collect(Collectors.toList())));
            }
        }
        // Same major.minor across all specs — declare the highest patch version encountered.
        String highest = versions.get(0);
        for (String version : versions) {
            if (compareVersions(version, highest) > 0) {
                highest = version;
            }
        }
        return highest;
    }

    /**
     * Returns {@code true} if {@code version} is a well-formed OpenAPI version: exactly three ASCII

View on GitHub (pinned to fcec517be3)

Solutions

  1. Upgrade or downgrade all source specs to one major.minor line (convert 3.0 specs to 3.1, or the reverse) before merging.
  2. If a spec only differs in patch (3.0.1 vs 3.0.3), align them anyway for clean output — though patches already merge to the highest.
  3. Split the merge into two runs, one per version line, if migration must be staged.
  4. Use a converter (e.g. swagger-converter / openapi-diff tooling) to bring stragglers onto the chosen line.

Example fix

# before
pet.yaml:    openapi: 3.0.1
store.yaml:  openapi: 3.1.0
# after (align all to one line)
pet.yaml:    openapi: 3.1.0
store.yaml:  openapi: 3.1.0
Defensive patterns

Strategy: validation

Validate before calling

// All specs must share one major.minor before merging
Set<String> majorMinor = specFiles.stream()
        .map(f -> readOpenapiField(f))
        .filter(Objects::nonNull)
        .map(v -> v.substring(0, v.lastIndexOf('.')))
        .collect(Collectors.toSet());
if (majorMinor.size() > 1) throw new IllegalArgumentException("Mixed versions: " + majorMinor);

Try / catch

Catch RuntimeException containing "incompatible OpenAPI versions"; print the distinct version set, then route specs into per-version merge runs or convert them.

Prevention

When it happens

Trigger: Merging pet.yaml (openapi: 3.0.1) with store.yaml (openapi: 3.1.0); introducing a newly-authored 3.1 spec (for e.g. nullable/examples changes) into an existing 3.0 catalog.

Common situations: Gradual 3.0→3.1 migrations where some teams converted early; mixed tooling emitting different default versions; pulling third-party specs with a different baseline into an internal merge.

Related errors


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