Stack Trace Formatter

Paste a crash dump. Frames split into function, file, and line. Vendor paths dim so the first file you own is the one you open.

Crash dump desk

Printer
Known dumps
Printer: Auto

Raw dump

0 characters

Frames

Waiting for a paste
Frames
0
Application
0
Vendor
0
Open this
-

Open the first file your team wrote

Chrome, Node, Java, and C# print the newest call on top. Python prints the newest call at the bottom. People who live in one of those printers read the other one backwards for years.

The dump sitting in Slack starts with node_modules/express/lib/router/layer.js. Half the room opens Express. The bug lives six frames down in lookup.js, on a property access against a missing host. Framework frames are cover. Walk past them until a path under the application repo shows up.

A stack trace formatter does one job here. Split each frame into function, file, and line. Dim the vendor ones. Pin the first application call so nobody argues about which line to open.

The dump never runs. Sourcemaps stay unresolved. Native frames stay opaque.

Text in, frames out

This desk reads the characters you paste. A webpack bundle pointing at line 1, column 1 stays at line 1, column 1. Apply the map in DevTools or in the error tracker before you argue about the line number. Async gaps stay missing. The runtime dropped those frames before the dump reached you.

  1. Read the exception type before any frame. TypeError, KeyError, and NullPointerException already name the class of mistake.
  2. Find the first path under the application repo. That is the file to open, not the first line of the dump.
  3. Ignore webpack:// until a sourcemap exists. Line 1:1 on a minified bundle is a fingerprint, not a location.
  4. If the application frame is a one-line wrapper, step into the caller. Wrappers exist to make dumps look tidy. They hide the real call.

Printers disagree on direction

Same crash. Different paper. The formatter has to know which printer wrote the dump, or the pin lands on the wrong end.

PrinterNewest callWhere the exception sitsA frame looks like
V8 (Chrome, Node)TopFirst lineat resolveHost (lookup.js:23:45)
FirefoxTopFirst lineresolveHost@https://toolexe.com/assets/lookup.js:23:45
Java / C#TopFirst line, then Caused by or inner exception blocks belowat com.toolexe.lookup.HostResolver.resolve(HostResolver.java:23)
PHPTopFirst line, sometimes repeated as thrown in at the end#0 /opt/toolexe/app/Lookup.php(23): App\Lookup->resolveHost()
Python / RubyBottomLast lineFile "/opt/toolexe/app/lookup.py", line 23, in resolve_host
GoTop of each goroutinepanic: line, then one block per goroutineFunction on one line, file.go:23 on the next

Auto reads those patterns and picks a printer. Mixed dumps fool it. A Python traceback pasted under a Node worker log will score as Python if a File "...", line line is present. Switch the printer by hand when the pin looks wrong.

Skip vendor, then come back

Most nights the first application frame is the right door.

Some nights the defect lives in the library. A Spring release that throws on a null older builds swallowed. A Laravel middleware order after an upgrade. A Go standard library change in net/http. Skip vendor first. If the application frame looks innocent, walk back into the library with the version number in hand.

Vendor here means a path match, not a verdict. node_modules, vendor/, site-packages, org.springframework, Microsoft.AspNetCore, node:internal, and java.base all dim. A first-party package published under a vendor-shaped folder will dim too. Unhide the frames and read the path before you file a ticket against Express.

Java truncates with ... 32 more. Those missing frames are the ones you need on a deep call into Spring. Reproduce under a debugger, or raise -XX:MaxJavaStackTraceDepth, when the dump stops at a framework adapter.

webpack:// is not a folder on disk

Bundlers rewrite locations. The dump then names a virtual path, a hash, or a single-letter function. Opening that path in the repo does nothing, because the file never existed on disk in that shape.

This page will not apply a sourcemap. There is no upload, no .map picker, and no attempt to guess sourcesContent. Error trackers such as Sentry apply the map on ingest. Chrome DevTools applies the map when the file was served with a sourceMappingURL. Paste the mapped dump if you already have one. Paste the raw dump if you do not, and treat line 1:1 on a .min.js as a dead end until a map exists.

Single-letter names, .min.js, and bundle.js trip a minified warning on the pin. The warning is a prompt to go get the map, not a claim about the code.

If the dump is still on the clipboard, paste it in the desk above. Auto picks the printer in most cases. Switch the language by hand when Node frames sit under a Python traceback, which happens in mixed workers.

Back to the dump

Home directories ride along

/home/deploy/. C:\Users\build\. /Users/ plus a laptop login. Those prefixes survive into tickets, screenshots, and Slack threads. The desk runs in the tab, so the dump is not uploaded. The paste still leaks a username the moment formatted output lands in a public issue.

Redact the prefix before the ticket leaves the team. Keep the filename and the line. Drop the account folder. The bug report template generator is the right next desk when the formatted frames need to travel with reproduction steps, because a raw dump in the ticket body is how home directories escape.

A leak flag appears on the pin when a frame path matches a user folder. The flag does not redact for you. Copy, then strip.

Three ways to read the same dump

Pinned cards
Each frame is a block with function, short name, and full path. The application frame to open stays in a pin above the list. Use this when you are still hunting.
One line each
Index, function, file:line. Use this when the dump is long and you already know the pin. Copy is cleaner in this mode because each frame is one line of text.
Field grid
Function, file, line, column, and full path as labeled fields. Use this when you are writing the location into a ticket and you do not want to re-parse a compact line by eye.

Hide vendor frames once the pin looks right. The counts at the bottom still include hidden frames, so a dump with 4 application frames and 40 Express frames still reads as 44.

Frames this desk will not invent

Runtimes drop frames. The formatter has nothing to reconstruct them from.

A dump with no matching frames is not a failed paste. The first line still shows as the exception. The rest of the text did not match a known frame pattern for the selected printer. Switch printer, or load a known dump above to see what a match looks like.

You have a file. Now what?

Open the pinned file at the pinned line. If the file is JavaScript and the line looks like a missing brace, the JavaScript syntax checker compiles the snippet without running it. A parse error and a TypeError are different desks. Mixing them wastes the next hour.

If the same exception repeats across requests, stop formatting one dump. Take the log file to the error log analyzer and count the signature. One formatted crash is a location. A counted signature is a priority.

Need a trail of what you already tried? The debug session recorder stores notes against the incident so the next person does not rerun the same dead end. Live console noise during a reproduce belongs on the real-time error checker, which is a different question from reading a dump that already happened.

Questions from people who already pasted a dump

Printer direction, vendor dimming, sourcemaps, and why frames go missing.

Why is the first line of the dump not the file I should open?

On V8, Java, C#, PHP, and Go, the newest call is on top, and the newest call is often a framework adapter. The file you own sits further down. On Python the newest call is at the bottom, so reading from the top lands you in the caller that started the request. The pin named Open this is the first application path in the correct direction for the selected printer.

Does Auto always pick the right language?

No. Auto scores known patterns. A Python File line inside a mixed worker log beats a Node at line. A Java at com.foo.Bar(File.java:12) line beats a JavaScript at foo (file.js:1:2) line when both are present. If the pin looks wrong, pick the printer by hand. The Printer label above the frames shows what Auto chose.

What counts as a vendor frame?

A path or class matching node_modules, vendor/, site-packages, org.springframework, org.apache, Microsoft.AspNetCore, System.Runtime, laravel/framework, node:internal, java.base, webpack/runtime, or a Native Method. First-party code published under a vendor-shaped folder will match too. Unhide the frames and read the path before you blame the library.

Will this apply my sourcemap?

No. There is no map upload and no guess at sourcesContent. Line 1:1 on a minified bundle stays at 1:1. Apply the map in DevTools or in the error tracker, then paste the mapped dump. The minified warning on the pin is a prompt to go get the map.

Is the dump uploaded?

No. Parsing, vendor matching, copy, and the known dumps all run in the tab. Cut the network after the page has loaded and the desk still works. Home directories in the path still leak the moment you paste formatted output into a public ticket. Redact the prefix.

Why did some lines in the dump disappear?

Only lines that match a frame pattern for the selected printer become frames. Indented Python source under a File line, Java ... n more markers, PHP thrown in repeats, and log timestamps on the same line as a frame are skipped or kept as exception text. Switch printer if a whole dump produces zero frames.

Chrome and Python both say at. Which way do I read?

Chrome does not say File, line. Python does not say at func (file:line:col). If you are reading by eye, newest-on-top for Chrome, Node, Java, C#, PHP, and Go. Newest-on-bottom for Python and Ruby. The pin follows that rule so you do not have to remember it at 2am.

The application frame is a one-line wrapper. Is that the bug?

Often no. Wrappers exist to translate library errors into application errors. Open the wrapper, then step to the caller the wrapper invoked. If the wrapper is innocent, unhide vendor frames and read the library version from the path or from the lockfile.