apply() is the only error boundary: mic.setProcessor(...).catch((e) => logger.warn(...)). Every failure mode — missing denoise/*.wasm (the assets are copied by cinny's vite plugin, not bundled by this repo, see the ⚠️ CONTRACT note at lotusDenoiseProcessor.ts:38-43), a browser that won't give a 16 kHz context for DTLN (lotusDenoiseProcessor.ts:220), a DFN ESM that moved — ends as a console warning. The user keeps publishing unprocessed audio, cinny's denoise toggle still reads "on", and there is no fallback to a simpler model. There is also no fromWidget message back to the host to report the failure, unlike every other lotus feature which has a host channel.
How to trigger
Delete/rename anything under public/element-call/denoise/, or pick DTLN on a browser that clamps AudioContext sample rates, and join a call.
Suggested fix
On init failure, retry once with model: "rnnoise" (the smallest, most portable tier) and, if that also fails, send a fromWidget failure notice so cinny can reflect the real state in its denoise toggle.
Filed from the September 2026 audit (branch lotus).
**Severity:** medium · **Type:** bug · **Confidence:** high
**Location:** `src/lotus/lotusDenoise.ts:102-106`
### Problem
`apply()` is the only error boundary: `mic.setProcessor(...).catch((e) => logger.warn(...))`. Every failure mode — missing `denoise/*.wasm` (the assets are copied by cinny's vite plugin, not bundled by this repo, see the `⚠️ CONTRACT` note at `lotusDenoiseProcessor.ts:38-43`), a browser that won't give a 16 kHz context for DTLN (`lotusDenoiseProcessor.ts:220`), a DFN ESM that moved — ends as a console warning. The user keeps publishing unprocessed audio, cinny's denoise toggle still reads "on", and there is no fallback to a simpler model. There is also no `fromWidget` message back to the host to report the failure, unlike every other lotus feature which has a host channel.
### How to trigger
Delete/rename anything under `public/element-call/denoise/`, or pick DTLN on a browser that clamps `AudioContext` sample rates, and join a call.
### Suggested fix
On `init` failure, retry once with `model: "rnnoise"` (the smallest, most portable tier) and, if that also fails, send a `fromWidget` failure notice so cinny can reflect the real state in its denoise toggle.
---
_Filed from the September 2026 audit (branch `lotus`)._
jared
added this to the EC fork audit 2026-09 · Medium & Low milestone 2026-09-12 02:13:00 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: medium · Type: bug · Confidence: high
Location:
src/lotus/lotusDenoise.ts:102-106Problem
apply()is the only error boundary:mic.setProcessor(...).catch((e) => logger.warn(...)). Every failure mode — missingdenoise/*.wasm(the assets are copied by cinny's vite plugin, not bundled by this repo, see the⚠️ CONTRACTnote atlotusDenoiseProcessor.ts:38-43), a browser that won't give a 16 kHz context for DTLN (lotusDenoiseProcessor.ts:220), a DFN ESM that moved — ends as a console warning. The user keeps publishing unprocessed audio, cinny's denoise toggle still reads "on", and there is no fallback to a simpler model. There is also nofromWidgetmessage back to the host to report the failure, unlike every other lotus feature which has a host channel.How to trigger
Delete/rename anything under
public/element-call/denoise/, or pick DTLN on a browser that clampsAudioContextsample rates, and join a call.Suggested fix
On
initfailure, retry once withmodel: "rnnoise"(the smallest, most portable tier) and, if that also fails, send afromWidgetfailure notice so cinny can reflect the real state in its denoise toggle.Filed from the September 2026 audit (branch
lotus).