Soenneker.OpenApi.Fixer
11.0.438
Prefix Reserved
dotnet add package Soenneker.OpenApi.Fixer --version 11.0.438
NuGet\Install-Package Soenneker.OpenApi.Fixer -Version 11.0.438
<PackageReference Include="Soenneker.OpenApi.Fixer" Version="11.0.438" />
<PackageVersion Include="Soenneker.OpenApi.Fixer" Version="11.0.438" />
<PackageReference Include="Soenneker.OpenApi.Fixer" />
paket add Soenneker.OpenApi.Fixer --version 11.0.438
#r "nuget: Soenneker.OpenApi.Fixer, 11.0.438"
#:package Soenneker.OpenApi.Fixer@11.0.438
#addin nuget:?package=Soenneker.OpenApi.Fixer&version=11.0.438
#tool nuget:?package=Soenneker.OpenApi.Fixer&version=11.0.438
Soenneker.OpenApi.Fixer
Normalize OpenAPI JSON documents that contain naming, schema, reference, enum, or composition patterns that commonly break generated clients.
Installation
dotnet add package Soenneker.OpenApi.Fixer
Registration
using Soenneker.OpenApi.Fixer.Registrars;
services.AddOpenApiFixerAsScoped();
AddOpenApiFixerAsSingleton() is also available for applications that share the fixer.
Fix a document
Inject IOpenApiFixer, then provide separate source and target paths:
using Soenneker.OpenApi.Fixer.Abstract;
await fixer.Fix(
"openapi.json",
"openapi.fixed.json",
cancellationToken);
The fixer reads JSON, normalizes the document, and writes formatted JSON. It uses a temporary file in the target directory and replaces an existing target only after the result parses successfully. Cancellation and processing failures propagate to the caller.
The fixer logs source and target file paths, major processing stages, temporary output and validation paths, completion timing, warnings, and errors by default. Set OpenApiFixerOptions.VerboseLogging to true to also see detailed progress, repair summaries, and individual repair details.
Input recovery accepts comments, trailing commas, unescaped control characters in strings, and bare True, False, and None values. Quoted text is preserved. Duplicate JSON properties use the last occurrence and produce a warning; conflicting duplicate values are inherently ambiguous. Version detection runs after recovery, so malformed JSON does not prevent an otherwise readable version from being recognized.
The preprocessing rules also recover numeric version metadata, quoted numeric constraints, singleton required/enum/composition collections, and singleton parameter objects. Missing route placeholders receive required string parameters only where no path-level or operation-level definition exists, including local parameter references. Existing parameter types and constraints are retained.
JSON schema traversal follows OpenAPI structure through callbacks, webhooks, reusable components, Swagger definitions, and nested JSON Schema keywords. Properties named example, type, or x-* receive the same repairs as other properties. These traversal passes treat examples, defaults, constants, enum values, and extensions as payload data instead of nested schema definitions. Separate compatibility passes can still normalize enum and default values. Numeric exclusive bounds in OpenAPI 3.1 and media-type parameters and ranges are preserved.
Recovery cannot infer missing contracts from arbitrary text or resolve conflicting definitions without a policy. Unrecoverable JSON and unsupported versions still fail explicitly. Final validation reads the exact output without preprocessing it again, and a failed or canceled run leaves an existing target intact.
The default normalization focuses on generated-client compatibility, including component and operation names, references, inline schemas, compositions, discriminators, enum representations, media types, defaults, and empty structures. These are material contract transformations: keep the source file, review the output diff, and generate and test the client before publishing it.
Optional transformations
By default, missing JSON media schemas are inferred from inline examples or locally referenced Example Objects. Inferred schemas combine observed properties and array element types without declaring fields required or inventing enums. Explicit schemas remain authoritative; nested integer formats are widened to int64 when payload examples demonstrate values outside Int32. This includes reusable schemas. Example payloads and vendor extensions, including response inference warnings, are preserved. No external examples are downloaded and no HTTP success status is guessed by the fixer.
Set InferSchemasFromExamples = false to disable this recovery. Media schemas created from examples carry x-schema-inferred-from-examples: true.
Pass OpenApiFixerOptions when you need behavior beyond the defaults:
using Microsoft.OpenApi;
using Soenneker.OpenApi.Fixer;
var options = new OpenApiFixerOptions
{
OutputSpecVersion = OpenApiSpecVersion.OpenApi3_1,
Int32IdTransform = true,
StripDateSuffixesFromGeneratedNames = true,
RedactCredentialLikeValues = true
};
await fixer.Fix(
"openapi.json",
"openapi.fixed.json",
options,
cancellationToken);
OutputSpecVersionoverrides the serialized OpenAPI version. When omitted, the source version is preserved.Int32IdTransformchanges integer properties and parameters ending inIdfromint32toint64.StripDateSuffixesFromGeneratedNamesremoves trailing date tokens from generated path prefixes, operation IDs, and schema names.RedactCredentialLikeValuesremoves credential-like values from examples and descriptions. It is disabled by default because it intentionally changes documentation content.
Logging
Turn on diagnostics for a call with one flag:
var options = new OpenApiFixerOptions { VerboseLogging = true };
await fixer.Fix("openapi.json", "openapi.fixed.json", options, cancellationToken);
VerboseLogging defaults to false. Progress and verbose messages use Information severity; warnings and errors are always available. The host's logging filters still apply. The flag is captured per call, applies to built-in helpers, and is isolated between concurrent calls, including singleton use. Standalone preprocessing accepts the same flag.
Repair generated enum members
Kiota can emit invalid C# identifiers for symbolic enum values. After generation, repair those identifiers without changing their serialized wire values:
await fixer.SanitizeGeneratedEnumMembers(
"GeneratedClient",
cancellationToken);
Only generated .cs files carrying Kiota or auto-generated markers are considered. A missing directory is ignored.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net11.0 is compatible. |
-
net11.0
- Microsoft.OpenApi (>= 3.11.0)
- Soenneker.Utils.Directory (>= 11.0.980)
- Soenneker.Utils.File (>= 11.0.2342)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Soenneker.OpenApi.Fixer:
| Package | Downloads |
|---|---|
|
Soenneker.Coinbase.Runners.OpenApiClients.Cdp
This runner executes a GitHub action that updates another project. It's not meant for consumption. |
|
|
Soenneker.HighLevel.Runners.OpenApiClient
Automatically updates the Soenneker.HighLevel.OpenApiClient package |
|
|
Soenneker.HubSpot.Runners.OpenApiClient
This runner executes a GitHub action that updates another project. It's not meant for consumption. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 11.0.438 | 673 | 11/14/2026 |
| 11.0.437 | 1,759 | 11/11/2026 |
| 11.0.436 | 348 | 11/11/2026 |
| 11.0.435 | 278 | 11/11/2026 |
| 11.0.434 | 310 | 11/11/2026 |
| 11.0.433 | 242 | 11/11/2026 |
| 11.0.432 | 508 | 11/11/2026 |
| 11.0.431 | 161 | 11/11/2026 |
| 11.0.430 | 6,978 | 11/3/2026 |
| 11.0.429 | 276 | 11/3/2026 |
| 11.0.428 | 674 | 11/3/2026 |
| 11.0.427 | 480 | 11/3/2026 |
| 11.0.426 | 289 | 11/3/2026 |
| 11.0.425 | 753 | 11/2/2026 |
| 11.0.424 | 245 | 11/2/2026 |
| 11.0.423 | 690 | 11/2/2026 |
| 11.0.422 | 493 | 11/2/2026 |
| 11.0.421 | 532 | 11/2/2026 |
| 11.0.420 | 253 | 11/2/2026 |
| 11.0.419 | 361 | 11/1/2026 |
Share generated union schema matchers across factories