You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Error.captureStackTrace throws 'First argument must be an Error object' after a delegating Error.prepareStackTrace wrapper is installed #41151
On Bun (JSC), once a delegating wrapper is installed on Error.prepareStackTrace — i.e. any wrapper that calls the original native prepareStackTrace — every subsequent call to Error.captureStackTrace(...) throws:
TypeError: First argument must be an Error object
even though the first argument really is an Error instance (instanceof Error === true, correct prototype chain).
The same code runs fine on Node.js (V8). This breaks real-world packages that combine stack-rewriting (Babel, source-map-support) with V8-style stack capture (follow-redirects, etc.): a running example is @vue/cli-service serve (webpack 4 toolchain) failing to boot under Bun.
Minimal reproduction
// min.js — Bun v1.4.0: exits 1 with the TypeError below// Node.js: prints "OK"constold=Error.prepareStackTrace// Delegating wrapper — the standard pattern, used e.g. by// @babel/core/lib/errors/rewrite-stack-trace.js and source-map-supportError.prepareStackTrace=(err,trace)=>old(err,trace)// V8-style stack capture (as used by follow-redirects' createErrorType)functionCustomError(){Error.captureStackTrace(this,this.constructor)}CustomError.prototype=newError()newCustomError()console.log("OK")
$ bun min.js
TypeError: First argument must be an Error object
at new CustomError (/private/tmp/min.js:11:9)
at /private/tmp/min.js:15:1
Bun v1.4.0 (macOS x64)
Trigger conditions (minimized by subtraction)
Variant
Result
No wrapper, plain Error.captureStackTrace(this, this.constructor)
✅ OK
Wrapper installed that does not call the original (e.g. () => String(err), or one that merely closes over it)
✅ OK
Wrapper installed that calls the originalprepareStackTrace ((err, trace) => old(err, trace), with 1 or 2 args, named or anonymous, installed before or after the first captureStackTrace call)
❌ throws
So the trigger is specifically: a Error.prepareStackTrace wrapper that delegates to the native implementation, followed by any Error.captureStackTrace call. The wrapper does not need to be invoked between the two; mere installation is enough.
Real-world impact
Under Bun, @vue/cli-service serve (Vue CLI 4 / webpack 4) crashes at startup:
@vue/cli-plugin-babel apply → babel.loadPartialConfigSync() permanently installs Babel's prepareStackTrace rewriter (which delegates to the previous one)
later, webpack-dev-server loads follow-redirects, whose createErrorType constructor calls Error.captureStackTrace(this, this.constructor) → process exits with TypeError: First argument must be an Error object
Workaround applied in the meantime: wrap Error.captureStackTrace in try/catch before starting the CLI (degrades to losing a few internal stack frames).
Reproduced: the repro throws TypeError: First argument must be an Error object on 1.4.1 canary, Node prints OK. The native default Error.prepareStackTrace rejected any target that is not a native Error instance.
Fix in progress: #41153
The fix is in #41395 (the default Error.prepareStackTrace accepts any object, as Error.captureStackTrace does). I verified the repro from this issue against that branch: new CustomError() no longer throws and .stack is "Error", the same as Node. #41153 was a duplicate of it and is closed.
Still reproducible with Bun 1.4.4 (5d9cc0f4f) on macOS arm64. Instrumenting source with [email protected] installs Babel's stack formatter and triggers the same failure for prototype-based error constructors:
import{createInstrumenter}from"istanbul-lib-instrument";createInstrumenter({esModules: true}).instrumentSync("export function example() { return 1; }","/tmp/example.js",);functionCustomError(){Error.captureStackTrace(this,this.constructor);}CustomError.prototype=newError();newCustomError();
Run with bun repro.mjs. Expected: construction succeeds. Actual: TypeError: First argument must be an Error object. This also prevents [email protected] from loading after instrumentation. Moving instrumentation into a separate worker avoids the process-global formatter interaction without changing the error constructor or suppressing stack capture.
Additional downstream impact: this prevents SAP AI Core provider imports in OpenCode's source-run server, not just stack display. Report and independent upstream reproduction: anomalyco/opencode#54791 (comment).
The path is OpenTUI/Solid → Babel's process-global stackTraceRewriter, followed by @sap-cloud-sdk/util → axios → follow-redirects. The import fails in follow-redirects' createErrorType / CustomError at Error.captureStackTrace(this, this.constructor), before any SAP authentication or model request. OpenCode's released 2.0.26 binary passed initialization in the upstream comparison; source execution with the Solid preload failed.
I also reduced it to Babel's public API, with no OpenCode, SAP SDK, credentials, or network calls needed after dependency installation:
Bun 1.4.4: formatter changed: true, then TypeError: First argument must be an Error object.
Node 24.13.0: formatter changed: true, then construction succeeds.
Bun 1.4.4, restoring the captured formatter immediately after transformSync as a diagnostic control: construction succeeds.
Babel already tracks its global formatter leak in babel/babel#16099. Linking these rather than opening a duplicate. The native formatter compatibility fix in #41395 remains the underlying runtime fix; globally swallowing stack-capture exceptions is not needed to reproduce or diagnose this.
Activity
robobun commentedon Sep 2, 2026
Reproduced: the repro throws TypeError: First argument must be an Error object on 1.4.1 canary, Node prints OK. The native default Error.prepareStackTrace rejected any target that is not a native Error instance.
Fix in progress: #41153
robobun commentedon Sep 5, 2026
The fix is in #41395 (the default
Error.prepareStackTraceaccepts any object, asError.captureStackTracedoes). I verified the repro from this issue against that branch:new CustomError()no longer throws and.stackis"Error", the same as Node. #41153 was a duplicate of it and is closed.address review: cover the elided-stack case from oven-sh#41151
Run the tests and mutation testing on Bun
CaliLuke commentedon Nov 3, 2026
Still reproducible with Bun 1.4.4 (
5d9cc0f4f) on macOS arm64. Instrumenting source with[email protected]installs Babel's stack formatter and triggers the same failure for prototype-based error constructors:Run with
bun repro.mjs. Expected: construction succeeds. Actual:TypeError: First argument must be an Error object. This also prevents[email protected]from loading after instrumentation. Moving instrumentation into a separate worker avoids the process-global formatter interaction without changing the error constructor or suppressing stack capture.ton618to commentedon Nov 8, 2026
Additional downstream impact: this prevents SAP AI Core provider imports in OpenCode's source-run server, not just stack display. Report and independent upstream reproduction: anomalyco/opencode#54791 (comment).
The path is OpenTUI/Solid → Babel's process-global
stackTraceRewriter, followed by@sap-cloud-sdk/util→ axios → follow-redirects. The import fails infollow-redirects'createErrorType/CustomErroratError.captureStackTrace(this, this.constructor), before any SAP authentication or model request. OpenCode's released 2.0.26 binary passed initialization in the upstream comparison; source execution with the Solid preload failed.I also reduced it to Babel's public API, with no OpenCode, SAP SDK, credentials, or network calls needed after dependency installation:
Observed locally on macOS arm64:
formatter changed: true, thenTypeError: First argument must be an Error object.formatter changed: true, then construction succeeds.transformSyncas a diagnostic control: construction succeeds.Babel already tracks its global formatter leak in babel/babel#16099. Linking these rather than opening a duplicate. The native formatter compatibility fix in #41395 remains the underlying runtime fix; globally swallowing stack-capture exceptions is not needed to reproduce or diagnose this.
chore(website): run the scripts on Bun