Free .NET developer tool
.NET Stack Trace Cleaner
Paste an exception from a log. See the root cause and the line in your code that threw, with async state machines, lambdas and local functions turned back into the names you wrote.
Runs entirely in your browser — nothing you paste is uploaded.
Pasted from JSON logs (Application Insights, Seq, a ProblemDetails body)? Escaped \r\n sequences are unescaped automatically. Nothing is sent anywhere.
What happened
Root causeMicrosoft.Data.SqlClient.SqlException
Your codeOrderService.CreateAsync.SaveAsyncasynclocal function — OrderService.cs:58
17 frames · 3 in your code · 4 demangled
Microsoft.EntityFrameworkCore.DbUpdateException- Shop.Api.Orders.OrderService.CreateAsync.SaveAsync()asynclocal functionOrderService.cs:58
- Shop.Api.Orders.OrderService.CreateAsync(CreateOrder request, CancellationToken ct)OrderService.cs:41
- Shop.Api.Orders.OrderEndpoints.MapOrders()asynclambdaOrderEndpoints.cs:22
Microsoft.Data.SqlClient.SqlException0x80131904ClientConnectionId:5b1e7c1a-2f0d-4a51-9c35-1f3c2e8f6a77 Error Number:2601,State:1,Class:14
Cleaned text
The same trace in Exception.ToString() layout, ready to paste into a ticket.
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert duplicate key row in object 'dbo.Orders' with unique index 'IX_Orders_Number'. The duplicate key value is (SO-1042).
… 4 framework frames
ClientConnectionId:5b1e7c1a-2f0d-4a51-9c35-1f3c2e8f6a77
Error Number:2601,State:1,Class:14
--- End of inner exception stack trace ---
… 4 framework frames
at Shop.Api.Orders.OrderService.CreateAsync.SaveAsync() [async, local function] in OrderService.cs:line 58
at Shop.Api.Orders.OrderService.CreateAsync(CreateOrder request, CancellationToken ct) in OrderService.cs:line 41
at Shop.Api.Orders.OrderEndpoints.MapOrders() [async, lambda] in OrderEndpoints.cs:line 22
… 4 framework framesReading compiler-generated names
C# features such as async, lambdas, iterators and local functions don't exist in IL. The compiler rewrites them into ordinary classes and methods with names you can't write yourself (they contain < and >), and those names appear in stack traces:
// What the compiler generates → What you wrote
<GetOrderAsync>d__5.MoveNext() → async Task GetOrderAsync()
<>c.<Main>b__0_0(Order o) → o => … (a lambda in Main, captures nothing)
<>c__DisplayClass5_0.<Find>b__0(Order o) → o => o.Id == id (a lambda in Find, captures id)
<Run>g__Load|2_0() → void Load() { … } (a local function in Run)
<<Run>g__LoadAsync|2_0>d.MoveNext() → async Task LoadAsync() (async local function)
Program.<Main>$(String[] args) → top-level statements in Program.cs
Repository`1..ctor(DbContext db) → the Repository<T> constructorWhy there are so many System and Microsoft frames
Every await that rethrows adds a --- End of stack trace from previous location --- line, and in .NET Framework also TaskAwaiter and ExceptionDispatchInfo frames. ASP.NET Core adds a frame for every middleware component. They're real, but rarely where the bug is. This page folds them so the frames from your own code stand out. Expand a folded group when the problem is in how you call a library.
Getting the exception text
Log the exception object rather than its Message, as in logger.LogError(ex, "Saving order {Id} failed", id): the logger then records ex.ToString(), with inner exceptions and stack traces. ex.Message alone loses both.
Frequently asked questions
What do names like <GetAsync>d__5.MoveNext mean in a .NET stack trace?
They are types and methods the C# compiler generates. An async method or iterator becomes a state machine class named <Method>d__N, and its body runs in MoveNext, so <GetAsync>d__5.MoveNext is your GetAsync method. Lambdas compile to <Method>b__N methods, often on a <>c or <>c__DisplayClass closure class, and local functions to <Method>g__Name|N. Since .NET Core 2.1 the runtime prints async methods by their real names, but lambdas and local functions are still shown mangled.
Where is the real error in an exception with inner exceptions?
Usually in the innermost one. Exception.ToString prints the outer exception first, then each inner exception after " ---> ", and the inner exception’s stack trace ends with "--- End of inner exception stack trace ---". Wrappers such as DbUpdateException, TargetInvocationException and AggregateException say what was being attempted; the innermost exception says what actually failed. In code, Exception.GetBaseException() returns it.
Is this like Ben.Demystifier?
It does a similar job on text you already have. Ben.Demystifier is a NuGet package that rewrites stack traces at run time (exception.Demystify()) using reflection, so it can also restore generic arguments, return types and tuple names. This page needs no code change or redeploy: paste a trace from a log, Application Insights or a support ticket and read it cleaned up.
Why are there no file names or line numbers in my stack trace?
Line numbers come from the PDB symbol files. If the PDBs aren’t deployed next to the assemblies, or DebugType is none, frames show only the method. Set <DebugType>portable</DebugType> or embedded in the project file and publish the .pdb files (embedded puts them inside the DLL). Release builds still have line numbers, though inlining can make them point at a caller.