OpenApiSecurityRequirement serializes as empty object when constructed programmatically with OpenApiSecuritySchemeReference #2801
Copy link
Copy link
Labels
priority:p1High priority but not blocking. Causes major but not critical loss of functionality SLA <=7daysHigh priority but not blocking. Causes major but not critical loss of functionality SLA <=7daystype:bugA broken experienceA broken experience
Description
Activity
- addedtype:questionAn issue that's a questionAn issue that's a questionstatus:waiting-for-author-feedbackIssue that we've responded but needs author feedback to closeIssue that we've responded but needs author feedback to close
on Mar 30, 2026 Hi Jonas Lewin (@jonaslewin)
Thank you for using the SDK and for reaching out.Have you tried with the latest versions? As you can see, I've added a unit test with pretty much the same code you've shared, and it's passing in #2802
Let me know if you have any additional comments or questions.
- addedtype:bugA broken experienceA broken experiencepriority:p1High priority but not blocking. Causes major but not critical loss of functionality SLA <=7daysHigh priority but not blocking. Causes major but not critical loss of functionality SLA <=7daysand removedtype:questionAn issue that's a questionAn issue that's a questionstatus:waiting-for-author-feedbackIssue that we've responded but needs author feedback to closeIssue that we've responded but needs author feedback to close
on Mar 30, 2026 Actually nevermind, the test results I had locally were outdated. The CI failed. I'll look further into this tomorrow.
(pushed the fix)
Metadata
Metadata
Assignees
Labels
priority:p1High priority but not blocking. Causes major but not critical loss of functionality SLA <=7daysHigh priority but not blocking. Causes major but not critical loss of functionality SLA <=7daystype:bugA broken experienceA broken experience
When building an
OpenApiDocumentprogrammatically and adding security requirements usingOpenApiSecuritySchemeReferenceas dictionary keys inOpenApiSecurityRequirement, the serialized output produces"security": [{}]instead of"security": [{"Bearer": []}].The root cause is in
OpenApiSecurityRequirement.SerializeInternal(), which filters entries with:When the document is constructed in memory (not parsed from a file),
Targetresolves viaReference.HostDocument.ResolveReferenceTo<U>(Reference, ...), which returns null because the security scheme was added toComponents.SecuritySchemesas a plainOpenApiSecurityScheme, not as anIOpenApiSecuritySchemethat the resolver can match. The filter silently drops the entry with no warning.To Reproduce
Expected behavior
{ "security": [ { "Bearer": [] } ] }Actual behavior
{ "security": [ {} ] }No exception or warning is produced — the entry is silently dropped.
Version
SerializeAsV3/V31/V32methods share the sameSerializeInternalcode path.Additional context
Microsoft.OpenApi.ODatato generate an OpenAPI document from an EDM model and then adding security definitions programmatically.OpenApiSecurityRequirementand overrideSerializeAsV3/SerializeAsV31/SerializeAsV32to write the security scheme name directly viaIOpenApiWriter.Suggested fix
The
Wherefilter inSerializeInternalshould fall back toReference.ReferenceV3(orReference.Id) whenTargetis null, rather than silently skipping the entry. Thecallbackalready usess.Reference.ReferenceV3for the property name — the guard just needs to allow entries where the reference ID is available even ifTargetcouldn't be resolved.