Skip to content

TransactionNameProvider is never called for routed requests #5123

@sentry-junior

Description

@sentry-junior

Summary

TransactionNameProvider is only invoked when the transaction name is empty (i.e. routing failed entirely). When ASP.NET Core routing resolves a route template successfully, the provider is silently skipped — making it impossible to partially materialize route parameters in the transaction name without writing a custom middleware.

Current behavior

In SentryTracingMiddleware, the TransactionNameProvider delegate is guarded by:

if (transaction.Name == string.Empty)
{
    transaction.Name = options.TransactionNameProvider?.Invoke(ctx) ?? ...;
}

Because routing resolves route templates like GET /api/v4/objects/{objectTypeName}/{objectId}/{operation}, transaction.Name is already populated before the provider is consulted. The delegate is never called.

Gap

There is no SDK-level hook that runs unconditionally after routing resolves and allows the transaction name to be rewritten. The full matrix of available hooks:

Hook Status
TransactionNameProvider Only fires when routing fails (name is empty) — unusable for routed requests
SetBeforeSendTransaction transaction.Name is private set; NameSource has no setter — read-only
ITransactionProcessor / AddTransactionProcessor Same constraint — name is not writable

The practical workaround today is to inject a custom ASP.NET middleware that runs after routing and rewrites the transaction name via SentrySdk.GetSpan() or similar. This is undiscoverable and fragile.

A related issue (#3106) was closed with the same custom-middleware workaround.

Options

Option A — Unconditional TransactionNameProvider invocation
Remove (or make optional) the if (transaction.Name == string.Empty) guard. Let the provider run on every routed request. A null return falls back to the SDK default. This is the smallest possible change and preserves backward compatibility for users who don't configure a provider.

Option B — Expose a mutable ITransactionContext in SetBeforeSendTransaction
Add a writable Name and NameSource to the type passed into SetBeforeSendTransaction / transaction processors. This is a broader API surface change but gives maximum flexibility.

Option C — Add a dedicated TransactionProcessor hook with mutation support
Introduce a post-routing pipeline hook (e.g. OnTransactionNameResolved) that receives the resolved route data and can return a replacement name.

Recommendation

Option A is the lowest-risk path: make TransactionNameProvider fire unconditionally and treat a null return as "keep the SDK default." This directly fixes the documented (but broken) use case with no breaking API change.

Action taken on behalf of a Sentry support escalation.

Metadata

Metadata

Labels

.NETPull requests that update .net codeFeatureNew feature or request
No fields configured for issues without a type.

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions