Bug
In packages/typescript-client/src/client.ts, the subscribe() method calls this.#start() without .catch():
subscribe(callback, onError = () => {}) {
const subscriptionId = {}
this.#subscribers.set(subscriptionId, [callback, onError])
if (!this.#started) this.#start() // ← no .catch()
return () => { this.#subscribers.delete(subscriptionId) }
}
When an unrecoverable error occurs, #start() routes the error to subscribers via #sendErrorToSubscribers() (which calls the registered onError callbacks), then the promise rejects. Because there's no .catch() attached, this rejection is unhandled — crashing Node.js and Bun processes, which treat unhandled rejections as fatal by default.
Why this is inconsistent
The same this.#start() call pattern in PauseLock.onReleased (line 750) already has this exact fix with an explanatory comment:
this.#start().catch(() => {
// Errors from #start are handled internally via onError.
// This catch prevents unhandled promise rejection in Node/Bun.
})
The subscribe() path was missed.
Suggested fix
Apply the identical pattern:
if (!this.#started) this.#start().catch(() => {
// Errors from #start are handled internally via onError.
// This catch prevents unhandled promise rejection in Node/Bun.
})
No behavior change — errors are already delivered to onError callbacks before the rejection propagates; this only prevents the unnecessary process crash.
Bug
In
packages/typescript-client/src/client.ts, thesubscribe()method callsthis.#start()without.catch():When an unrecoverable error occurs,
#start()routes the error to subscribers via#sendErrorToSubscribers()(which calls the registeredonErrorcallbacks), then the promise rejects. Because there's no.catch()attached, this rejection is unhandled — crashing Node.js and Bun processes, which treat unhandled rejections as fatal by default.Why this is inconsistent
The same
this.#start()call pattern inPauseLock.onReleased(line 750) already has this exact fix with an explanatory comment:The
subscribe()path was missed.Suggested fix
Apply the identical pattern:
No behavior change — errors are already delivered to
onErrorcallbacks before the rejection propagates; this only prevents the unnecessary process crash.