Problem Statement
The existing childProcessIntegration (in packages/node-core) captures breadcrumbs and errors for child processes and worker threads. It works by subscribing to Node.js's internal node:diagnostics_channel channels (child_process and worker_threads), which Node.js publishes to from its C++ layer when a subprocess is spawned.
This approach does not work on Bun for two reasons:
-
Bun fully implements the node:diagnostics_channel API, but does not publish to the child_process or worker_threads channels when spawning processes. The subscriptions are registered but never fire.
Verified by testing: subscribing to diagnostics_channel.channel('child_process') on Bun never fires, even when spawning via node:child_process. Even with the not-deprecated method.
-
Bun exposes its own native subprocess API — Bun.spawn() / Bun.spawnSync() — which returns a Bun.Subprocess object. This has no EventEmitter; exit and error handling go through an onExit callback option and a proc.exited promise, not .on('exit') / .on('error').
As a result, users running Sentry on Bun get no child process breadcrumbs, even if they import and configure childProcessIntegration from the node sdk.
Solution Brainstorm
Since Bun doesn't hook into diagnostics_channel for subprocesses, the integration must intercept process creation differently. Two monkey-patch targets should do the trick:
-
node:child_process compat layer — Bun implements the Node.js child_process module and its ChildProcess objects do support .on('spawn'), .on('exit'), and .on('error'). Patching cp.spawn and cp.fork is sufficient; exec / execFile delegate to spawn at the JS level. (Yes, that abbreviation is unfortunate)
-
Bun.spawn — Bun's native API. Bun.Subprocess has no EventEmitter, so the integration wraps the caller's onExit callback to capture exit codes and spawn errors. Bun.spawn supports two call signatures that both need handling:
Bun.spawn(cmd: string[], options?)
Bun.spawn(options: { cmd: string[] } & SpawnOptions)
Worker threads are intentionally out of scope for now — node:worker_threads is not yet fully supported in Bun and important features are missing. Ref: 1, 2
A reference implementation is available as a Gist: https://gist.github.com/The-LukeZ/ca83a14e9ddb24295c74112a3c2ac9a2 (I've tested it and it doesn't error at least)
Idea of the Bun integration's setup():
setup() {
// 1. Patch node:child_process (compat layer)
for (const method of ['spawn', 'fork']) {
const original = cp[method];
cp[method] = function (...args) {
const child = original.apply(this, args);
captureChildProcessEvents(child, options); // same EventEmitter logic as Node integration
return child;
};
}
// 2. Patch Bun.spawn (native)
const originalSpawn = Bun.spawn.bind(Bun);
Bun.spawn = function (cmdOrOptions, spawnOptions) {
const userOnExit = resolvedOptions.onExit;
return originalSpawn(cmdOrOptions, {
...resolvedOptions,
onExit(proc, exitCode, signalCode, error) {
// addBreadcrumb on non-zero exit or error
userOnExit?.(proc, exitCode, signalCode, error);
},
});
};
}
Additional Context
I took the code from the integration from node-core to draft that Bun integration.
-
Affected package: A new integration in packages/bun.
-
Bun subprocess docs: https://bun.com/docs/runtime/child-process
-
Bun diagnostics_channel compatibility: https://bun.com/reference/node/diagnostics_channel — listed as "Fully implemented" for the API, but Bun does not internally publish to 'child_process' channel events.
-
The sw_vers guard from the Node integration should be preserved — Sentry pings /usr/bin/sw_vers on macOS to collect OS context and should not generate a breadcrumb for that.
-
I am not in a position to open a PR (not enough knowledge to follow the contribution guidelines and no time for all the setup), but a working reference implementation is provided in the Gist linked above for whoever picks this up.
Priority
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.
Problem Statement
The existing
childProcessIntegration(inpackages/node-core) captures breadcrumbs and errors for child processes and worker threads. It works by subscribing to Node.js's internalnode:diagnostics_channelchannels (child_processandworker_threads), which Node.js publishes to from its C++ layer when a subprocess is spawned.This approach does not work on Bun for two reasons:
Bun fully implements the
node:diagnostics_channelAPI, but does not publish to thechild_processorworker_threadschannels when spawning processes. The subscriptions are registered but never fire.Bun exposes its own native subprocess API —
Bun.spawn()/Bun.spawnSync()— which returns aBun.Subprocessobject. This has noEventEmitter; exit and error handling go through anonExitcallback option and aproc.exitedpromise, not.on('exit')/.on('error').As a result, users running Sentry on Bun get no child process breadcrumbs, even if they import and configure
childProcessIntegrationfrom the node sdk.Solution Brainstorm
Since Bun doesn't hook into
diagnostics_channelfor subprocesses, the integration must intercept process creation differently. Two monkey-patch targets should do the trick:node:child_processcompat layer — Bun implements the Node.jschild_processmodule and itsChildProcessobjects do support.on('spawn'),.on('exit'), and.on('error'). Patchingcp.spawnandcp.forkis sufficient;exec/execFiledelegate tospawnat the JS level. (Yes, that abbreviation is unfortunate)Bun.spawn— Bun's native API.Bun.Subprocesshas no EventEmitter, so the integration wraps the caller'sonExitcallback to capture exit codes and spawn errors.Bun.spawnsupports two call signatures that both need handling:Bun.spawn(cmd: string[], options?)Bun.spawn(options: { cmd: string[] } & SpawnOptions)Worker threads are intentionally out of scope for now —
node:worker_threadsis not yet fully supported in Bun and important features are missing. Ref: 1, 2A reference implementation is available as a Gist: https://gist.github.com/The-LukeZ/ca83a14e9ddb24295c74112a3c2ac9a2 (I've tested it and it doesn't error at least)
Idea of the Bun integration's
setup():Additional Context
I took the code from the integration from
node-coreto draft that Bun integration.Affected package: A new integration in
packages/bun.Bun subprocess docs: https://bun.com/docs/runtime/child-process
Bun
diagnostics_channelcompatibility: https://bun.com/reference/node/diagnostics_channel — listed as "Fully implemented" for the API, but Bun does not internally publish to'child_process'channel events.The
sw_versguard from the Node integration should be preserved — Sentry pings/usr/bin/sw_verson macOS to collect OS context and should not generate a breadcrumb for that.I am not in a position to open a PR (not enough knowledge to follow the contribution guidelines and no time for all the setup), but a working reference implementation is provided in the Gist linked above for whoever picks this up.
Priority
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding
+1orme too, to help us triage it.