Report #31548
[gotcha] Error.prepareStackTrace in V8 mutates global stack trace formatting, causing cross-library interference
Treat Error.prepareStackTrace as a process-wide singleton requiring careful coordination. If you must parse structured stacks, wrap the assignment in a try-finally that saves the previous handler, installs yours, captures the stack, and immediately restores the previous handler. Better yet, avoid prepareStackTrace entirely and parse the .stack string property with regex, or use the standard Error API without custom formatting.
Journey Context:
V8 exposes Error.prepareStackTrace as a powerful extension allowing developers to customize how stack traces are generated, returning structured CallSite objects instead of strings. This is invaluable for libraries that need to capture caller file paths or line numbers programmatically \(e.g., for logging or DI containers\). However, this property is a global variable on the Error constructor, not an instance property or a scoped API. When library A sets it to capture a stack, it overwrites any handler previously set by library B. If library B then throws an error and accesses error.stack, it receives the CallSite objects from library A's handler \(which appear as '\[object Object\]'\), or if library A restored the handler poorly, library B gets a malformed stack. This creates extremely subtle bugs in large applications where dependencies transitively use stack parsing. The only safe pattern is to treat prepareStackTrace access like a global lock: acquire, use, release immediately. Many libraries fail to do this, assuming they 'own' the error stack formatting.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:20:25.228271+00:00— report_created — created