Summary
In voice/audio_recognition.ts, benign AbortErrors from the EOU (end-of-utterance) detection task on normal turn/session teardown are logged at error level as Error in EOU detection task:, and the error serializes as a DOMException numeric constant table ({ ABORT_ERR: 20, DATA_CLONE_ERR: 25, ... }) rather than a useful message. This produces error-level log noise on essentially every turn.
Root cause
The bounceEOUTask result handler tries to swallow aborts:
this.bounceEOUTask.result.then(() => {
this.logger.debug("EOU detection task completed");
}).catch((err) => {
if (err instanceof Error && err.message.includes("This operation was aborted")) {
return;
}
this.logger.error(err, "Error in EOU detection task:");
});
The abort raised by AbortController/AbortSignal is a DOMException with name === 'AbortError', and under Node/Bun:
- A
DOMException is not instanceof Error, so the first condition is already false.
- Its message is
"The operation was aborted." (note "The", not "This"), so the includes("This operation was aborted") substring check would miss it even if instanceof Error passed.
Both conditions fail, so the expected abort falls through to this.logger.error(...). Because the value is a DOMException (not a normal Error), the structured logger emits its enumerable constant table instead of name/message.
Environment
@livekit/agents 1.3.4
- Node/Bun runtime (observed on Bun 1.2.23, Linux x64)
Suggested fix
Detect aborts by name, which is robust across runtimes and message wording:
}).catch((err) => {
if (err?.name === 'AbortError') {
return;
}
this.logger.error(err, "Error in EOU detection task:");
});
(Optionally also normalize non-Error throwables before logging so any genuinely unexpected DOMException still logs a readable name/message.)
Summary
In
voice/audio_recognition.ts, benignAbortErrors from the EOU (end-of-utterance) detection task on normal turn/session teardown are logged at error level asError in EOU detection task:, and the error serializes as aDOMExceptionnumeric constant table ({ ABORT_ERR: 20, DATA_CLONE_ERR: 25, ... }) rather than a useful message. This produces error-level log noise on essentially every turn.Root cause
The
bounceEOUTaskresult handler tries to swallow aborts:The abort raised by
AbortController/AbortSignalis aDOMExceptionwithname === 'AbortError', and under Node/Bun:DOMExceptionis notinstanceof Error, so the first condition is already false."The operation was aborted."(note "The", not "This"), so theincludes("This operation was aborted")substring check would miss it even ifinstanceof Errorpassed.Both conditions fail, so the expected abort falls through to
this.logger.error(...). Because the value is aDOMException(not a normalError), the structured logger emits its enumerable constant table instead ofname/message.Environment
@livekit/agents1.3.4Suggested fix
Detect aborts by name, which is robust across runtimes and message wording:
(Optionally also normalize non-
Errorthrowables before logging so any genuinely unexpectedDOMExceptionstill logs a readablename/message.)