Skip to main content

Changelog

This page records issues discovered and resolved while hardening the library. All entries are fully resolved — none represent open bugs. The detailed engineering notes for each fix live in docs/known-issues/ (mirrors the GitHub bug-report template; kept as a developer reference).

Core DI

IDSummarySeverity
001Open-generic pipeline behavior registrations throw at runtime under Native AOT when TResponse is a value typeHigh
002ValidateOnBuild = false does not suppress the issue-001 runtime errorMedium
004AddValidator registers a validator that is never wired into the pipeline — validation silently never runsHigh
015EnableCqrsBoundaryEnforcement() was an [Obsolete] no-op; runtime-API callers silently lost all enforcementHigh
019Behavior dedup compared (ServiceType, ImplementationType) only — lifetime-blind, skipped factory/instance registrationsMedium

Source Generator

IDSummarySeverity
005Generator emits an uncompilable type name for nested handler/behavior classes (drops enclosing-type chain)High
006Open-generic behavior closed with the interface's arity, not the class's own → CS0305High
012GlobalizeType emits invalid global:: prefix for tuple / pointer / function-pointer typesMedium
017SplitTopLevelArgs ignored tuple () — a tuple nested as a generic argument emitted uncompilable codeMedium
022[Validator] derived the response type from the first IRequest<T> found; multi-IRequest requests now emit diagnostic MDG011Low
024Open-generic behavior special constraints (class/struct/unmanaged/notnull/new()) were dropped, closing the behavior over non-conforming handlers → uncompilable code (CS0453); now captured as equatable flags and enforced in the cross-productHigh
025Generated RegisterGroup namespace was derived from the assembly name, ignoring MSBuild RootNamespace; it now reads build_property.RootNamespace first (and a new [RegisterGroup] partial class lets users pick the namespace/name explicitly)Medium

Pipeline & CQRS

IDSummarySeverity
008Cross-assembly open-generic behavior is registered (and runs) twice — no dedup on the user-behavior pathHigh
009Order is only a generator-local sort; runtime order follows DI registration across sourcesMedium
013Invoker overloads resolve handlers inconsistently (static TRequest vs runtime request.GetType())Medium
016CQRS boundary marker leaked when a handler threw — spurious violation on later send in the same scopeMedium
018CQRS enforcement was emitted per-discovered-handler only — manually registered handlers were not coveredMedium
021EventDispatcher re-sorted behaviors via OrderBy on every publish (per-publish allocation)Low

Outbox

IDSummarySeverity
010Outbox event lookup narrowed to ReferenceEquals — broke the public contract for equal-but-distinct eventsMedium
014Outbox lookup matched the first value-equal event across all scopes; stored items now carry a stable Guid identity via OutboxEntryHigh
020Outbox "failed count" counted retrying events (Attempts > 0), tripping the health check on transient retriesMedium
023RecordOutbox* metric methods were dead no-ops on ISynapseMetrics (superseded by observable gauges); removedLow

Observability

IDSummarySeverity
007Outbox observable gauges are never registered; Record* are no-ops so outbox metrics emit nothingHigh
011Tracing capture stores zero/invalid trace IDs (empty-string guard never fires) and stringifies twiceMedium

ASP.NET Core

IDSummarySeverity
003Pipeline short-circuit via Result.Failure<T>() mapped to HTTP 500; behavior now returns a typed UnauthorizedFailure → 401Medium

Discovery context: Issues 001–003 were found while building the pipeline-behavior showcase in examples/MinimalApi on branch feature/typed-pipeline-behaviors against .NET 10 with PublishAot=true. Issues 004–023 were found in successive high-effort code reviews of the same branch (diff + working-tree, multiple finder angles). All are resolved. Line numbers in the individual files are approximate and may drift as the branch evolves.