Handle equivalent duplicate schemas in multi-spec merge#1076
Conversation
…stories - Merged inbox decision files into decisions.md under 2026-04-28 entry - Documented e-conomic multi-spec merge failure root cause and approved fix - Updated agent history files (Ripley, Parker, Dallas, Lambert) with session findings - Added skill documentation for multi-source-openapi-tooling diagnostics Decision: e-conomic duplicate schema failure approved for fix in Refitter.Core AreEquivalent() to be replaced with OpenAPI-aware canonical comparison. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📝 WalkthroughWalkthroughThis PR implements a fix for multi-spec OpenAPI merge failures by replacing strict schema equivalence checking with canonical JSON token comparison. The solution accepts structurally identical duplicate schemas (like Changes
Sequence DiagramsequenceDiagram
participant Gen as RefitGenerator
participant Merge as OpenApiDocumentFactory<br/>.Merge()
participant Canon as Canonicalization<br/>Utilities
participant Token as JToken<br/>Comparison
Gen->>Merge: CreateAsync(multi-spec paths)
Merge->>Merge: Process document 1,<br/>document 2
Merge->>Merge: Detect duplicate<br/>schema name (Error)
Merge->>Canon: AreEquivalent(schema1,<br/>schema2)
Canon->>Canon: Normalize schema1<br/>to JToken
Canon->>Canon: Normalize schema2<br/>to JToken
Canon->>Token: JToken.DeepEquals
Token-->>Canon: true (equivalent)
Canon-->>Merge: true
Merge->>Merge: Accept duplicate,<br/>skip merge
Merge-->>Gen: Merged document<br/>(no conflict)
Gen->>Gen: Generate code
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/Refitter.Tests/RegressionTests/MultiSpecSchemaMergeTests.cs (1)
243-263: Add explicit fixture-existence assertions for clearer failures.Right now missing files fail deeper in generation. A direct check near path construction gives faster and clearer diagnostics.
Based on learnings: "Test CLI changes with a real OpenAPI specification to ensure generation works correctly."🧪 Suggested test-hardening diff
public async Task Economic_OpenApiPaths_Generate_NonEmpty_Buildable_Code() { var repositoryRoot = GetRepositoryRoot(); var productsSpec = Path.Combine(repositoryRoot, "test", "OpenAPI", "v3.0", "economic-products.json"); var webhooksSpec = Path.Combine(repositoryRoot, "test", "OpenAPI", "v3.0", "economic-webhooks.json"); + File.Exists(productsSpec).Should().BeTrue($"expected fixture at '{productsSpec}'"); + File.Exists(webhooksSpec).Should().BeTrue($"expected fixture at '{webhooksSpec}'"); var settings = new RefitGeneratorSettings { OpenApiPaths = [productsSpec, webhooksSpec], Namespace = "Economic" };Also applies to: 292-302
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Refitter.Tests/RegressionTests/MultiSpecSchemaMergeTests.cs` around lines 243 - 263, In the test Economic_OpenApiPaths_Generate_NonEmpty_Buildable_Code add explicit assertions that the OpenAPI fixture files exist before calling RefitGenerator.CreateAsync: after constructing productsSpec and webhooksSpec assert File.Exists(productsSpec) and File.Exists(webhooksSpec) (or equivalent) so failures fail fast and clearly; apply the same pattern to the other test that uses OpenAPI fixture paths (the one around the second OpenApiPaths usage) to ensure both specs are present before generation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.squad/orchestration-log/2026-04-28T15-21-48+02-00-lambert.md:
- Around line 6-8: Update the log entry to use the current test filename instead
of the pre-rename name and fix the malformed generated-file path by restoring
the missing leading character; specifically replace the stale
"src\Refitter.Tests\RegressionTests\Issue1016_MultiSpecSchemaMergeTests.cs"
reference with the repository's current test path/name and change
"est\GeneratedCode\economic.cs" to the correct "test\GeneratedCode\economic.cs"
(or the actual expected generated-code path) so both entries reflect valid,
up-to-date paths.
---
Nitpick comments:
In `@src/Refitter.Tests/RegressionTests/MultiSpecSchemaMergeTests.cs`:
- Around line 243-263: In the test
Economic_OpenApiPaths_Generate_NonEmpty_Buildable_Code add explicit assertions
that the OpenAPI fixture files exist before calling RefitGenerator.CreateAsync:
after constructing productsSpec and webhooksSpec assert
File.Exists(productsSpec) and File.Exists(webhooksSpec) (or equivalent) so
failures fail fast and clearly; apply the same pattern to the other test that
uses OpenAPI fixture paths (the one around the second OpenApiPaths usage) to
ensure both specs are present before generation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4c2caf13-11e6-4239-b4f2-0af0d39cf994
📒 Files selected for processing (24)
.squad/agents/ash/history.md.squad/agents/dallas/history.md.squad/agents/lambert/history.md.squad/agents/parker/history.md.squad/agents/ripley/history.md.squad/decisions.md.squad/log/2026-04-28T15-21-48+02-00-economic-openapi-implementation.md.squad/orchestration-log/2026-04-28T15-21-48+02-00-ash.md.squad/orchestration-log/2026-04-28T15-21-48+02-00-lambert.md.squad/orchestration-log/2026-04-28T15-21-48+02-00-parker.md.squad/skills/multi-source-openapi-tooling/SKILL.mdsrc/Refitter.Core/OpenApiDocumentFactory.cssrc/Refitter.Tests/OpenApiDocumentFactoryMergeTests.cssrc/Refitter.Tests/RegressionTests/ContractSuffixCorruptionTests.cssrc/Refitter.Tests/RegressionTests/DynamicQuerystringMutationTests.cssrc/Refitter.Tests/RegressionTests/EnumConverterInjectionTests.cssrc/Refitter.Tests/RegressionTests/MalformedUnicodeEscapeTests.cssrc/Refitter.Tests/RegressionTests/MultiSpecSchemaMergeTests.cssrc/Refitter.Tests/RegressionTests/OneOfDiscriminatorNullRefTests.cssrc/Refitter.Tests/RegressionTests/XmlDocEscapingTests.cstest/OpenAPI/v3.0/economic-products.jsontest/OpenAPI/v3.0/economic-webhooks.jsontest/economic.refittertest/multiple-sources.refitter
There was a problem hiding this comment.
Pull request overview
Updates Refitter’s multi-spec OpenAPI merge to treat semantically equivalent duplicate schemas as non-conflicting (fixing the e-conomic multi-spec scenario) while keeping fail-fast behavior for true conflicts.
Changes:
- Implement canonical JSON-based equivalence checks for duplicate items during merge (with a schema fallback for cyclic graphs).
- Add merge/regression tests covering equivalent duplicate schemas and the real e-conomic multi-spec generation/buildability.
- Add e-conomic settings/spec inputs under
test/for repro/regression.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| test/multiple-sources.refitter | Extends the sample multi-source settings to include the e-conomic specs. |
| test/economic.refitter | Adds a dedicated .refitter repro file for the e-conomic multi-spec case. |
| test/OpenAPI/v3.0/economic-webhooks.json | Adds the e-conomic webhooks OpenAPI document used in regression coverage. |
| src/Refitter.Core/OpenApiDocumentFactory.cs | Changes merge equivalence from serializer string compare to canonicalized JSON token comparison (plus schema fallback). |
| src/Refitter.Tests/OpenApiDocumentFactoryMergeTests.cs | Adds tests asserting equivalent duplicates are ignored (including recursive schema + Swagger2 definition coverage). |
| src/Refitter.Tests/RegressionTests/MultiSpecSchemaMergeTests.cs | Adds compile-backed regression for the real e-conomic multi-spec output and renames the test class. |
| src/Refitter.Tests/RegressionTests/XmlDocEscapingTests.cs | Renames regression test class. |
| src/Refitter.Tests/RegressionTests/OneOfDiscriminatorNullRefTests.cs | Renames regression test class. |
| src/Refitter.Tests/RegressionTests/MalformedUnicodeEscapeTests.cs | Renames regression test class. |
| src/Refitter.Tests/RegressionTests/EnumConverterInjectionTests.cs | Renames regression test class. |
| src/Refitter.Tests/RegressionTests/DynamicQuerystringMutationTests.cs | Renames regression test class. |
| src/Refitter.Tests/RegressionTests/ContractSuffixCorruptionTests.cs | Renames regression test class. |
| .squad/skills/multi-source-openapi-tooling/SKILL.md | Adds internal squad skill notes related to multi-source OpenAPI tooling. |
| .squad/orchestration-log/2026-04-28T15-21-48+02-00-parker.md | Adds squad orchestration log (gitignored path). |
| .squad/orchestration-log/2026-04-28T15-21-48+02-00-lambert.md | Adds squad orchestration log (gitignored path). |
| .squad/orchestration-log/2026-04-28T15-21-48+02-00-ash.md | Adds squad orchestration log (gitignored path). |
| .squad/log/2026-04-28T15-21-48+02-00-economic-openapi-implementation.md | Adds squad session log (gitignored path). |
| .squad/decisions.md | Records the e-conomic merge decision/validation notes. |
| .squad/agents/ripley/history.md | Updates agent history with e-conomic merge notes. |
| .squad/agents/parker/history.md | Updates agent history with e-conomic merge notes. |
| .squad/agents/lambert/history.md | Updates agent history with e-conomic merge notes. |
| .squad/agents/dallas/history.md | Updates agent history with e-conomic merge notes. |
| .squad/agents/ash/history.md | Updates agent history with e-conomic merge notes. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1076 +/- ##
==========================================
- Coverage 95.40% 95.14% -0.27%
==========================================
Files 27 27
Lines 2437 2326 -111
==========================================
- Hits 2325 2213 -112
- Misses 39 43 +4
+ Partials 73 70 -3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Refitter.Core/OpenApiDocumentFactory.cs`:
- Around line 326-327: The enum and composed-schema arrays aren’t canonicalized,
so reorderings cause false mismatches; when building schema JSON in
OpenApiDocumentFactory (the spot that currently sets json["enum"] from
actualSchema.Enumeration and the blocks that add "allOf","oneOf","anyOf" around
lines handling composed schemas), sort enum values and sort composed-schema
entries deterministically before adding them to the JArray (e.g. by stable
serialization or a comparer that canonicalizes each schema token), and replace
the direct Select/ToObject insertion with the sorted sequence so enum and
composed arrays are order-independent; apply the same deterministic ordering
logic to the other composed-schema handling at the other block (the one
referenced around lines 353-360).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a521f332-1455-40e7-80e1-8a8d7747e823
📒 Files selected for processing (2)
src/Refitter.Core/OpenApiDocumentFactory.cssrc/Refitter.Tests/OpenApiDocumentFactoryMergeTests.cs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Refitter.Tests/OpenApiDocumentFactoryMergeTests.cs
Updated [refitter](https://github.com/christianhelle/refitter) from 1.7.1 to 2.0.0. <details> <summary>Release notes</summary> _Sourced from [refitter's releases](https://github.com/christianhelle/refitter/releases)._ ## 2.0.0 ## What's Changed * Fix numeric format with pattern quirk - infer type from format for all numeric types by @Copilot in christianhelle/refitter#869 * Read group documentation from document tags. by @DJ4ddi in christianhelle/refitter#887 * Fix null reference and XML escaping in XmlDocumentationGenerator by @Copilot in christianhelle/refitter#890 * Fix build workflow: add dotnet restore before dotnet msbuild in Prepare step by @Copilot in christianhelle/refitter#892 christianhelle/refitter#895 * Fix MSBuild workflow by @christianhelle in christianhelle/refitter#898 * Add support for generating a single client from multiple OpenAPI specifications by @Copilot in christianhelle/refitter#904 * Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by @vgmello in christianhelle/refitter#907 * Improve Smoke Tests execution time by @christianhelle in christianhelle/refitter#915 * Fix #580: Nullable strings marked correctly by @christianhelle in christianhelle/refitter#921 * Fix #672: MultipleInterfaces ByTag method naming scoped per-interface by @christianhelle in christianhelle/refitter#922 * Fix #635: Refactor source generator to use context.AddSource() by @christianhelle in christianhelle/refitter#923 * Add custom format mappings configuration by @christianhelle in christianhelle/refitter#927 * Fix multipart form-data parameter extraction by @christianhelle in christianhelle/refitter#928 christianhelle/refitter#911 christianhelle/refitter#902 * Fix smoke tests: --interface-only variant missing using directive for contract types by @Copilot in christianhelle/refitter#933 * Fix SonarCloud Code Quality Issues by @Copilot in christianhelle/refitter#932 * Add debug logging for source generator when searching for .refitter files by @codymullins in christianhelle/refitter#743 * Fix: Base type not generated for types using oneOf with discriminator by @Copilot in christianhelle/refitter#906 * Add option for Method Level Authorization header attribute by @Roflincopter in christianhelle/refitter#897 * Fix PR #897 review feedback and add comprehensive bearer auth tests by @christianhelle in christianhelle/refitter#936 * Fix numeric suffix added to interface method names in ByTag mode by @Copilot in christianhelle/refitter#914 * Improve OpenAPI parse + codegen throughput by removing avoidable allocations and repeated regex work by @Copilot in christianhelle/refitter#937 * Move [JsonConverter] from enum properties to enum types by @christianhelle in christianhelle/refitter#938 * Fix broken CLI tool help text by @christianhelle in christianhelle/refitter#940 * Improve code coverage to >90% by @christianhelle in christianhelle/refitter#941 * Microsoft.OpenApi v3.4 by @christianhelle in christianhelle/refitter#945 * Add Unicode support for XML doc comment generation by @christianhelle in christianhelle/refitter#948 * Add PropertyNamingPolicy support for JSON property naming by @christianhelle in christianhelle/refitter#969 christianhelle/refitter#966 * Fix recursive schema stack overflows by @christianhelle in christianhelle/refitter#971 * Made Header Parameters for Security Schemes safe to use as C# variable name by @smoerijf in christianhelle/refitter#977 * Enhance schema alias handling and property name generation by @christianhelle in christianhelle/refitter#996 * Verify alias handling and sanitize PascalCase properties by @christianhelle in christianhelle/refitter#997 * Harden .refitter settings deserialization and output path handling by @christianhelle in christianhelle/refitter#1000 * Special-case the default .refitter filename before deriving OutputFilename by @coderabbitai[bot] in christianhelle/refitter#1002 * [v2.0 audit] Fix pre-release regressions from #1057 by @christianhelle in christianhelle/refitter#1064 * Resolve high-severity audit findings from #1057 by @christianhelle in christianhelle/refitter#1067 * [v2.0 audit] Close remaining verified #1057 regressions by @christianhelle in christianhelle/refitter#1070 * Harden generation flows by @christianhelle in christianhelle/refitter#1071 * Breaking changes and Migration Guide for v2.0.0 by @christianhelle in christianhelle/refitter#1009 * Handle equivalent duplicate schemas in multi-spec merge by @christianhelle in christianhelle/refitter#1076 * Tighten warning handling across Refitter builds by @christianhelle in christianhelle/refitter#1079 * Fix default solution path and update .NET version in VS Code config by @christianhelle in christianhelle/refitter#1082 * Fix docker smoke tests by @christianhelle in christianhelle/refitter#1081 * Sanitize malformed schema type names without renaming clean schemas by @christianhelle in christianhelle/refitter#1085 ... (truncated) ## 1.7.3 ## What's Changed * Add support for systems running only .NET 10.0 (without .NET 8.0 or 9.0) in Refitter.MSBuild by @christianhelle in christianhelle/refitter#882 * Update to return HttpResponseMessage for file downloads by @frogcrush in christianhelle/refitter#877 ## New Contributors * @frogcrush made their first contribution in christianhelle/refitter#877 **Full Changelog**: christianhelle/refitter@1.7.2...1.7.3 ## 1.7.2 **Implemented enhancements:** - Improve Immutable Records ergonomics [\#844](christianhelle/refitter#844) - Omit certain operation headers and include all others [\#840](christianhelle/refitter#840) - Create .refitter settings file as part of output [\#859](christianhelle/refitter#859) by @[christianhelle - Fix integerType enum deserialization issue [\#855](christianhelle/refitter#855) ([christianhelle](https://github.com/christianhelle)) - support custom nswag template directory \#844 [\#854](christianhelle/refitter#854) by @kmc059000 - Fix missing method parameter XML code-documentation [\#850](christianhelle/refitter#850) ([christianhelle](https://github.com/christianhelle)) **Fixed bugs:** - integerType parsing in settings file fails [\#851](christianhelle/refitter#851) - CS1573 : Method parameter has no matching XML comment [\#846](christianhelle/refitter#846) **Merged pull requests:** - docs: add frogcrush as a contributor for code [\#878](christianhelle/refitter#878) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - Migrate solution files from .sln to .slnx format [\#876](christianhelle/refitter#876) ([Copilot](https://github.com/apps/copilot-swe-agent)) - Fix issue with randomly failing tests to due parallel execution [\#872](christianhelle/refitter#872) ([christianhelle](https://github.com/christianhelle)) - chore\(deps\): update dependency tunit to 1.9.2 [\#863](christianhelle/refitter#863) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.7.7 [\#862](christianhelle/refitter#862) ([renovate[bot]](https://github.com/apps/renovate)) - Add unit tests for WriteRefitterSettingsFile functionality [\#860](christianhelle/refitter#860) ([Copilot](https://github.com/apps/copilot-swe-agent)) - chore\(deps\): update dependency ruby to v4 [\#858](christianhelle/refitter#858) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.6.28 [\#857](christianhelle/refitter#857) ([renovate[bot]](https://github.com/apps/renovate)) - docs: add 0x2badc0de as a contributor for bug [\#856](christianhelle/refitter#856) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - chore\(deps\): update dependency swashbuckle.aspnetcore to 10.1.0 [\#853](christianhelle/refitter#853) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.6.0 [\#852](christianhelle/refitter#852) ([renovate[bot]](https://github.com/apps/renovate)) - docs: add lilinus as a contributor for code [\#849](christianhelle/refitter#849) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - chore\(deps\): update dependency ruby to v3.4.8 [\#845](christianhelle/refitter#845) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.5.70 [\#837](christianhelle/refitter#837) ([renovate[bot]](https://github.com/apps/renovate)) **Full Changelog**: christianhelle/refitter@1.7.1...1.7.2 Commits viewable in [compare view](christianhelle/refitter@1.7.1...2.0.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated [Refitter.MSBuild](https://github.com/christianhelle/refitter) from 1.7.3 to 2.0.0. <details> <summary>Release notes</summary> _Sourced from [Refitter.MSBuild's releases](https://github.com/christianhelle/refitter/releases)._ ## 2.0.0 ## What's Changed * Fix numeric format with pattern quirk - infer type from format for all numeric types by @Copilot in christianhelle/refitter#869 * Read group documentation from document tags. by @DJ4ddi in christianhelle/refitter#887 * Fix null reference and XML escaping in XmlDocumentationGenerator by @Copilot in christianhelle/refitter#890 * Fix build workflow: add dotnet restore before dotnet msbuild in Prepare step by @Copilot in christianhelle/refitter#892 christianhelle/refitter#895 * Fix MSBuild workflow by @christianhelle in christianhelle/refitter#898 * Add support for generating a single client from multiple OpenAPI specifications by @Copilot in christianhelle/refitter#904 * Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by @vgmello in christianhelle/refitter#907 * Improve Smoke Tests execution time by @christianhelle in christianhelle/refitter#915 * Fix #580: Nullable strings marked correctly by @christianhelle in christianhelle/refitter#921 * Fix #672: MultipleInterfaces ByTag method naming scoped per-interface by @christianhelle in christianhelle/refitter#922 * Fix #635: Refactor source generator to use context.AddSource() by @christianhelle in christianhelle/refitter#923 * Add custom format mappings configuration by @christianhelle in christianhelle/refitter#927 * Fix multipart form-data parameter extraction by @christianhelle in christianhelle/refitter#928 christianhelle/refitter#911 christianhelle/refitter#902 * Fix smoke tests: --interface-only variant missing using directive for contract types by @Copilot in christianhelle/refitter#933 * Fix SonarCloud Code Quality Issues by @Copilot in christianhelle/refitter#932 * Add debug logging for source generator when searching for .refitter files by @codymullins in christianhelle/refitter#743 * Fix: Base type not generated for types using oneOf with discriminator by @Copilot in christianhelle/refitter#906 * Add option for Method Level Authorization header attribute by @Roflincopter in christianhelle/refitter#897 * Fix PR #897 review feedback and add comprehensive bearer auth tests by @christianhelle in christianhelle/refitter#936 * Fix numeric suffix added to interface method names in ByTag mode by @Copilot in christianhelle/refitter#914 * Improve OpenAPI parse + codegen throughput by removing avoidable allocations and repeated regex work by @Copilot in christianhelle/refitter#937 * Move [JsonConverter] from enum properties to enum types by @christianhelle in christianhelle/refitter#938 * Fix broken CLI tool help text by @christianhelle in christianhelle/refitter#940 * Improve code coverage to >90% by @christianhelle in christianhelle/refitter#941 * Microsoft.OpenApi v3.4 by @christianhelle in christianhelle/refitter#945 * Add Unicode support for XML doc comment generation by @christianhelle in christianhelle/refitter#948 * Add PropertyNamingPolicy support for JSON property naming by @christianhelle in christianhelle/refitter#969 christianhelle/refitter#966 * Fix recursive schema stack overflows by @christianhelle in christianhelle/refitter#971 * Made Header Parameters for Security Schemes safe to use as C# variable name by @smoerijf in christianhelle/refitter#977 * Enhance schema alias handling and property name generation by @christianhelle in christianhelle/refitter#996 * Verify alias handling and sanitize PascalCase properties by @christianhelle in christianhelle/refitter#997 * Harden .refitter settings deserialization and output path handling by @christianhelle in christianhelle/refitter#1000 * Special-case the default .refitter filename before deriving OutputFilename by @coderabbitai[bot] in christianhelle/refitter#1002 * [v2.0 audit] Fix pre-release regressions from #1057 by @christianhelle in christianhelle/refitter#1064 * Resolve high-severity audit findings from #1057 by @christianhelle in christianhelle/refitter#1067 * [v2.0 audit] Close remaining verified #1057 regressions by @christianhelle in christianhelle/refitter#1070 * Harden generation flows by @christianhelle in christianhelle/refitter#1071 * Breaking changes and Migration Guide for v2.0.0 by @christianhelle in christianhelle/refitter#1009 * Handle equivalent duplicate schemas in multi-spec merge by @christianhelle in christianhelle/refitter#1076 * Tighten warning handling across Refitter builds by @christianhelle in christianhelle/refitter#1079 * Fix default solution path and update .NET version in VS Code config by @christianhelle in christianhelle/refitter#1082 * Fix docker smoke tests by @christianhelle in christianhelle/refitter#1081 * Sanitize malformed schema type names without renaming clean schemas by @christianhelle in christianhelle/refitter#1085 ... (truncated) Commits viewable in [compare view](christianhelle/refitter@1.7.3...2.0.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>



Closes #1075
Summary
Fix multi-spec OpenAPI merging so Refitter accepts equivalent duplicate schemas instead of failing on them as collisions.
This resolves the
test\multiple-sources.refitterscenario where the e-conomic OpenAPI specs likeeconomic-products.jsonandeconomic-webhooks.jsonboth define shared schemas such asErrorandProblemDetails.What changed
Why
The input specs are valid as-is and should not need local edits. Refitter should merge equivalent shared schemas without requiring changes to the upstream e-conomic OpenAPI documents.
Validation
Summary by CodeRabbit
Bug Fixes
New Features
Documentation
Tests