OpenAPITools/openapi-generator · error · RuntimeException
Failed to serialize merged spec
Error message
Failed to serialize merged spec
What it means
The final step of mergeSpecs writes the merged OpenAPI object to disk with Jackson (Json or Yaml mapper with pretty printer); a JsonProcessingException during writeValueAsString is wrapped in this RuntimeException. Unlike sibling failures, the merge itself succeeded — serialization of the merged object failed, which usually indicates content in the merged tree Jackson cannot serialize (e.g., mixed mapper-annotated nodes) rather than bad input files.
Source
Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java:389
// -------------------------------------------------------------------------
// DEEP mode — full inline merge with component conflict detection
// -------------------------------------------------------------------------
private String buildDeepMergedSpec(ParsedSpecFiles parsed, String outputDir) {
OpenAPI merged = mergeSpecs(parsed.specs, parsed.allServers);
String mergedFilename = this.mergeFileName + (parsed.isJson ? ".json" : ".yaml");
Path mergedFilePath = Paths.get(outputDir, mergedFilename);
try {
Files.createDirectories(mergedFilePath.getParent());
String content = parsed.isJson
? Json.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(merged)
: Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(merged);
Files.write(mergedFilePath, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
} catch (JsonProcessingException e) {
throw new RuntimeException("Failed to serialize merged spec", e);
} catch (IOException e) {
throw new RuntimeException(e);
}
return mergedFilePath.toString();
}
/**
* Merges a list of parsed OpenAPI specs into a single spec.
*
* <p>Path items are merged by HTTP method: if two specs define the same URL path, their
* operations are combined (e.g. GET from one file + POST from another). Duplicate HTTP methods
* on the same path, conflicting component definitions, and duplicate {@code operationId}s are
* all treated as conflicts and handled according to the configured {@link MergeConflictStrategy}
* ({@link MergeConflictStrategy#WARN} keeps the first definition; {@link MergeConflictStrategy#FAIL}
* aborts).</p>
*
* <p>Component maps (schemas, responses, requestBodies, parameters, headers, examples,View on GitHub (pinned to fcec517be3)
Solutions
- Inspect the cause (the original JsonProcessingException is chained) — it names the offending type/property.
- Align Jackson and swagger-core versions with the openapi-generator distribution (dependency:tree / mvn dependencyConvergence).
- Use the official CLI jar to run the merge, isolating it from your application's classpath conflicts.
- Sanitize extension values in source specs (keep them plain maps/scalars).
Example fix
# before: app pins old jackson
implementation("com.fasterxml.jackson.core:jackson-databind:2.11.0")
# after: match the version openapi-generator ships
implementation("com.fasterxml.jackson.core:jackson-databind:2.17.+") Defensive patterns
Strategy: try-catch
Try / catch
try { builder.buildMergedSpec(); } catch (RuntimeException e) { Throwable root = Stream.iterate(e, Throwable::getCause).filter(Objects::nonNull).reduce((a, c) -> c).orElse(e); if (root instanceof JsonProcessingException) { /* report root.getMessage(): names the unserializable type; check jackson/swagger-models versions */ } throw e; } Prevention
- Run merges with the official CLI jar to isolate classpath.
- Enforce dependency convergence on jackson-databind and swagger-models.
- Keep spec extension values to plain maps, lists, and scalars.
When it happens
Trigger: Merged schema tree contains node types the Json/Yaml mapper cannot handle after cross-spec merging (e.g. incompatible swagger-core model versions on the classpath, or extension values that are not Jackson-serializable objects).
Common situations: Dependency conflicts pulling mismatched jackson-databind/swagger-models versions into the same classpath as openapi-generator; custom code mutating the parsed OpenAPI tree with non-serializable objects before merge output; very old/new Jackson on the path shading different versions.
Related errors
- inputSpecFiles list is empty — nothing to merge
- Spec directory doesn't contain any specification
- No valid specifications found to merge
- Cannot merge specs where some declare an OpenAPI version and
- Malformed OpenAPI version '%s' in a source spec. Expected ex
AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22).
Data as JSON: /api/errors/8702eb5f7cb87b17.
Report an issue: GitHub.