Skip to content
Purview Dev logo

OpenAPI XmlComments

Preview

Keeps the ASP.NET Core OpenAPI XML-comment generator working when one documentation ID arrives twice.

agent-skills aspnetcore build-tooling csharp dotnet msbuild nuget openapi source-generator xml-comments xml-documentation

The problem

An MSBuild package for APIs that reference Microsoft.AspNetCore.OpenApi. The XML-comment source generator builds one dictionary from the documentation of every project reference and of the API's own compilation, and de-duplicates neither, so a documented type that arrives from more than one assembly makes /openapi/v1.json answer 500 with "An item with the same key has already been added". This package removes every colliding documentation ID from the referenced XML documentation before compile, and warns (POAX001) about an ID it can only see once the API has been built. The generator stays on, so every XML description stays in the OpenAPI document.

From the repository

An MSBuild package that keeps the ASP.NET Core OpenAPI XML-comment source generator working when the same documentation ID comes from more than one assembly.

Why it became a project

The same 500 appeared in several APIs at once as soon as a source generator started injecting the same attribute into every assembly (dotnet/aspnetcore#67192). The usual workaround — removing the generator — also removed every description from the document, so the fix became two MSBuild targets that filter only what actually collides.

Where it fits

Use it when

Your API references Microsoft.AspNetCore.OpenApi with its XML-comment generator on, and a documented type with the same full name is compiled into more than one of its project references — typically an attribute or polyfill a source generator injects into every assembly.

It may not fit when

The duplicate never passes through AdditionalFiles, or both copies come from the API's own compilation: the package cannot see those, and a type that is genuinely duplicated public API needs one of the declarations renamed rather than filtered.

Use cases

Concrete examples of what OpenAPI XmlComments does, and who each one is for.

Developer

Keep the generator on and filter only what collides

/openapi/v1.json answers 500 with "An item with the same key has already been added" because a type your API documents is also documented in more than one referenced project, and the only workaround you have found turns the XML-comment generator off.

xml
<!-- the project that calls AddOpenApi() -->
<PackageReference Include="Purview.OpenAPI.XmlComments" Version="1.0.0" PrivateAssets="all" />

What you get: Every colliding documentation ID is removed from the referenced documentation before compile, the generator runs on the filtered copies, and the description of every other endpoint and schema stays in the document.

Every occurrence of a colliding ID goes, not all but the first, because the API usually declares the injected type as well: keeping a reference's copy would still collide with it. A duplicated ID is ambient code rather than API surface, and a copy is only rewritten when its content changes, so a no-change build still skips CoreCompile.

Read the guide →
Developer

List every colliding ID rather than the first one

The exception names one documentation ID, and the build says nothing about the rest, so you do not know whether one exclude is enough or whether the generator fails again on the next build.

powershell
pwsh skills/purview-openapi-xmlcomments-duplicates/scripts/find-duplicate-documentation-ids.ps1 `
  -Project path/to/Api

What you get: The script asks MSBuild for exactly the documentation files the generator reads and reports every colliding ID, where each copy comes from, whether the current configuration already handles it, and the item to add when it does not.

Each finding is classified: BetweenReferences is handled automatically by the package, while ReferenceAndProject needs the PurviewOpenAPIXmlCommentExclude item the script prints. It exits 0 when nothing would throw, 1 when something would, and 2 when it could not inspect the project.

Read the guide →
Team lead

Fail the build on a collision instead of a 500 in production

The overlap is only visible after the API compiles, so a warning is easy to ship, and the failure then surfaces as a 500 on the OpenAPI document rather than as a red build.

xml
<PropertyGroup>
  <!-- fail the build instead of leaving the collision to run time -->
  <MSBuildWarningsAsErrors>$(MSBuildWarningsAsErrors);POAX001</MSBuildWarningsAsErrors>
</PropertyGroup>

What you get: POAX001 fails the build and names the exact PurviewOpenAPIXmlCommentExclude item to add, so an unhandled collision is a pull-request failure instead of a runtime error.

The check runs after CoreCompile and compares the API's fresh documentation file with the filtered reference documentation, which is the one case the before-compile pass cannot see: an ID documented in the API and in exactly one referenced project.

Read the guide →
Architect

One repository-wide reference that costs nothing at run time

Several API projects in the same repository reference the same generators, and you do not want per-project wiring or a build fix that becomes a runtime dependency.

xml
<!-- Directory.Packages.props: once for every project in the repository -->
<GlobalPackageReference Include="Purview.OpenAPI.XmlComments" Version="1.0.0" />

What you get: One declaration covers every project and does nothing in a project that does not reference Microsoft.AspNetCore.OpenApi, so libraries in the same repository need no exemption.

The package ships only props, targets and a netstandard2.0 task assembly under tasks/; lib/, ref/ and runtimes/ are forbidden by pack validation, so it adds no runtime dependency and copies nothing into the consumer's build output.

Read the guide →

Packages

1 package

Purview.OpenAPI.XmlCommentsInstall ↓—1.0.0-prerelease.1—

Install

.NET CLI
dotnet add package Purview.OpenAPI.XmlComments

Agent skills

OpenAPI XmlComments authors agent skills for coding agents. They are installed explicitly with the skills CLI and are not part of any NuGet package.

Skills are installed explicitly with the skills CLI. Nothing ships them inside a NuGet package, and no build writes into your agent's directories: installation is a decision you make. Use whichever package manager you already have.

npm

Terminal window
npx skills add purview-dev/openapi-xmlcomments

bun

Terminal window
bunx skills add purview-dev/openapi-xmlcomments

pnpm

Terminal window
pnpm dlx skills add purview-dev/openapi-xmlcomments

yarn

Terminal window
yarn dlx skills add purview-dev/openapi-xmlcomments
  • Installs at project level by default. Add -g for a user-level install, or -a <agent> to target one agent.
  • To match the release you use, pin a commit or tag by appending #<ref> to any command above (for example npx skills add purview-dev/openapi-xmlcomments#<ref>).
  • The CLI records what it installed in skills-lock.json; restore it with the same runner:
Terminal window
npx skills experimental_install
  • purview-openapi-xmlcomments-duplicates

    Use when an ASP.NET Core OpenAPI document fails with "ArgumentException: An item with the same key has already been added" from XmlCommentCache.GenerateCacheEntries, /openapi/v1.json answers 500, the build warns POAX001, or a project removes the Microsoft.AspNetCore.OpenApi.SourceGenerators analyzer to avoid duplicate XML documentation members. Finds which documentation IDs collide and where each copy comes from, then installs and configures Purview.OpenAPI.XmlComments (PurviewOpenAPIXmlCommentExclude, PurviewOpenAPIXmlCommentDeduplication) and verifies the fix.

    4 files