{"record":{"id":"e6918ce944392d56","repo":"OpenAPITools/openapi-generator","slug":"component-s-name-conflict-during-spec-merge-s","errorCode":null,"errorMessage":"Component %s name conflict during spec merge: '%s' is defined in multiple specs with different definitions. Keeping the first definition.","messagePattern":"Component (.+?) name conflict during spec merge: '(.+?)' is defined in multiple specs with different definitions\\. Keeping the first definition\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java","lineNumber":809,"sourceCode":"        mergeComponentMap(target.getSecuritySchemes(), source.getSecuritySchemes(), \"securityScheme\", target::addSecuritySchemes);\n        // OpenAPI 3.1 reusable path items — without this, operations referencing\n        // '#/components/pathItems/...' would dangle in the merged output.\n        mergeComponentMap(target.getPathItems(), source.getPathItems(), \"pathItem\", target::addPathItem);\n    }\n\n    private <T> void mergeComponentMap(Map<String, T> existing, Map<String, T> incoming,\n                                       String typeName, java.util.function.BiConsumer<String, T> adder) {\n        if (incoming == null) {\n            return;\n        }\n        incoming.forEach((name, value) -> {\n            if (existing != null && existing.containsKey(name)) {\n                if (!Objects.equals(existing.get(name), value)) {\n                    String message = String.format(Locale.ROOT,\n                            \"Component %s name conflict during spec merge: '%s' is defined in multiple specs with different definitions. Keeping the first definition.\",\n                            typeName, name);\n                    if (conflictStrategy == MergeConflictStrategy.FAIL) {\n                        throw new RuntimeException(message);\n                    }\n                    LOGGER.warn(message);\n                }\n                // identical or keeping first — either way, skip\n            } else {\n                adder.accept(name, value);\n            }\n        });\n    }\n\n    private List<String> getAllSpecFilesInDirectory() {\n        Path rootDirectory = new File(inputSpecRootDirectory).toPath();\n        try (Stream<Path> pathStream = Files.walk(rootDirectory)) {\n            return pathStream\n                    .filter(path -> !Files.isDirectory(path))\n                    .filter(path -> {\n                        String name = path.getFileName().toString().toLowerCase(Locale.ROOT);\n                        return SPEC_EXTENSIONS.stream().anyMatch(name::endsWith);","sourceCodeStart":791,"sourceCodeEnd":827,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java#L791-L827","documentation":"MergedSpecBuilder.mergeComponentMap throws this when two merged specs declare the same component name (schema, parameter, response, securityScheme, ...) with DIFFERENT definitions and mergeConflictStrategy is FAIL. Identical duplicates are silently accepted; only differing definitions count as a conflict, where the first definition wins.","triggerScenarios":"Directory merge where petstore.yaml defines schema 'Pet' with 4 properties and store.yaml defines 'Pet' with 6. existing.containsKey(name) is true, Objects.equals(existing.get(name), value) is false, and FAIL aborts the merge with the component type and name in the message.","commonSituations":"Shared DTOs copy-pasted between team specs that later drift out of sync; common parameter components like 'limitParam' defined differently per file; a shared components file merged together with specs that inline-repeat those components.","solutions":["Align the component definitions so they are identical (Objects.equals) across every spec file.","Move the shared component into one canonical file and reference it via $ref from the other specs, removing the duplicates.","Rename one of the conflicting components (e.g. StorePet vs Pet) and update its $refs.","Drop the strict FAIL strategy if first-wins behavior is acceptable for your pipeline."],"exampleFix":"# specs/a.yaml (before):\ncomponents:\n  schemas:\n    Pet: { type: object, properties: { id: {type: integer}, name: {type: string} } }\n# specs/b.yaml (before):\ncomponents:\n  schemas:\n    Pet: { type: object, properties: { id: {type: string}, name: {type: string}, tag: {type: string} } }\n# after — both files carry the byte-identical Pet schema, or b.yaml renames:\n    StorePet: { type: object, properties: { id: {type: string}, name: {type: string}, tag: {type: string} } }","handlingStrategy":"validation","validationCode":"// Pre-flight: fail when the same component name has different definitions across specs\nMap<String, Object> merged = new HashMap<>();\nfor (String file : specFiles) {\n    OpenAPI api = new OpenAPIV3Parser().read(file);\n    if (api.getComponents() == null || api.getComponents().getSchemas() == null) continue;\n    api.getComponents().getSchemas().forEach((name, schema) -> {\n        Object prev = merged.get(name);\n        if (prev != null && !Objects.equals(prev, schema))\n            throw new IllegalStateException(\"Component '\" + name + \"' differs between specs\");\n        merged.put(name, schema);\n    });\n}","typeGuard":null,"tryCatchPattern":"try {\n    mergedSpec = mergedSpecBuilder.build();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Component \") && e.getMessage().contains(\"name conflict during spec merge\")) {\n        // diff the two component definitions, then align or rename them at source\n        throw new BuildException(\"Spec merge conflict: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Define shared components (schemas, parameters) once in a canonical file and $ref them instead of duplicating.","Treat a silently-differing duplicate component as data drift: even on WARN strategy the merge keeps only the first definition, which can change generated models.","Run a schema-diff check in CI when multiple specs reuse the same component names."],"tags":["openapi","spec-merge","components","schema-conflict","java"],"backgroundTag":"duplicate-component-definition","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}