{"record":{"id":"8702eb5f7cb87b17","repo":"OpenAPITools/openapi-generator","slug":"failed-to-serialize-merged-spec","errorCode":null,"errorMessage":"Failed to serialize merged spec","messagePattern":"Failed to serialize merged spec","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java","lineNumber":389,"sourceCode":"\n    // -------------------------------------------------------------------------\n    // DEEP mode — full inline merge with component conflict detection\n    // -------------------------------------------------------------------------\n\n    private String buildDeepMergedSpec(ParsedSpecFiles parsed, String outputDir) {\n        OpenAPI merged = mergeSpecs(parsed.specs, parsed.allServers);\n\n        String mergedFilename = this.mergeFileName + (parsed.isJson ? \".json\" : \".yaml\");\n        Path mergedFilePath = Paths.get(outputDir, mergedFilename);\n\n        try {\n            Files.createDirectories(mergedFilePath.getParent());\n            String content = parsed.isJson\n                    ? Json.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(merged)\n                    : Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(merged);\n            Files.write(mergedFilePath, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.WRITE);\n        } catch (JsonProcessingException e) {\n            throw new RuntimeException(\"Failed to serialize merged spec\", e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        return mergedFilePath.toString();\n    }\n\n    /**\n     * Merges a list of parsed OpenAPI specs into a single spec.\n     *\n     * <p>Path items are merged by HTTP method: if two specs define the same URL path, their\n     * operations are combined (e.g. GET from one file + POST from another). Duplicate HTTP methods\n     * on the same path, conflicting component definitions, and duplicate {@code operationId}s are\n     * all treated as conflicts and handled according to the configured {@link MergeConflictStrategy}\n     * ({@link MergeConflictStrategy#WARN} keeps the first definition; {@link MergeConflictStrategy#FAIL}\n     * aborts).</p>\n     *\n     * <p>Component maps (schemas, responses, requestBodies, parameters, headers, examples,","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java#L371-L407","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"# before: app pins old jackson\nimplementation(\"com.fasterxml.jackson.core:jackson-databind:2.11.0\")\n# after: match the version openapi-generator ships\nimplementation(\"com.fasterxml.jackson.core:jackson-databind:2.17.+\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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."],"tags":["openapi","spec-merge","serialization","jackson","dependency-conflict"],"backgroundTag":"serialization-failed","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}