Skip to content

fix: remove speaking listener on voice disconnect#25312

Closed
docaohieu2808 wants to merge 1 commit intoopenclaw:mainfrom
docaohieu2808:fix/voice-speaking-listener-cleanup
Closed

fix: remove speaking listener on voice disconnect#25312
docaohieu2808 wants to merge 1 commit intoopenclaw:mainfrom
docaohieu2808:fix/voice-speaking-listener-cleanup

Conversation

@docaohieu2808
Copy link
Copy Markdown
Contributor

@docaohieu2808 docaohieu2808 commented Feb 24, 2026

Summary

  • The speaking event handler (connection.receiver.speaking.on("start", ...)) was added on voice join but never removed on leave/destroy. On reconnects, old handlers accumulated — the stale closure captured the old entry, causing ghost audio captures and preventing GC of old session state.
  • Added .off("start", speakingHandler) in stop() before connection.destroy() to properly clean up the listener.

Test plan

  • Verify no duplicate speaking handlers after voice reconnect
  • Verify voice capture still works normally after join
  • Verify leave properly cleans up all listeners

Greptile Summary

Added proper cleanup of the speaking event listener on voice disconnect. The speakingHandler callback is now stored in a variable and explicitly removed via .off("start", speakingHandler) in the stop() method before destroying the connection. This prevents handler accumulation on reconnects and allows proper garbage collection of old session state.

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk - it addresses a clear memory leak issue
  • The fix correctly addresses the memory leak by cleaning up the speaking event listener. However, there are other event listeners (connection.on(VoiceConnectionStatus.Disconnected, ...), connection.on(VoiceConnectionStatus.Destroyed, ...), and player.on("error", ...)) that are also not being cleaned up in the stop() method, which could potentially cause similar issues
  • Pay close attention to src/discord/voice/manager.ts - verify that all event listeners are properly cleaned up

Last reviewed commit: 3635da7

@openclaw-barnacle openclaw-barnacle bot added channel: discord Channel integration: discord size: XS labels Feb 24, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 428 to 434
stop: () => {
if (speakingHandler) {
connection.receiver.speaking.off("start", speakingHandler);
}
player.stop();
connection.destroy();
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider also cleaning up other event listeners added to connection and player (lines 444, 455, 459). If the session is destroyed and recreated, these listeners may also accumulate, though the impact is less severe than the speaking handler since connection.destroy() may implicitly clean some of them up.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/discord/voice/manager.ts
Line: 428-434

Comment:
Consider also cleaning up other event listeners added to `connection` and `player` (lines 444, 455, 459). If the session is destroyed and recreated, these listeners may also accumulate, though the impact is less severe than the speaking handler since `connection.destroy()` may implicitly clean some of them up.

How can I resolve this? If you propose a fix, please make it concise.

Clean up all registered event listeners in stop() to prevent accumulation:
- speaking handler (receiver.speaking)
- disconnected handler (VoiceConnectionStatus.Disconnected)
- destroyed handler (VoiceConnectionStatus.Destroyed)
- player error handler

Addresses code review feedback to be thorough with listener cleanup.
@docaohieu2808 docaohieu2808 force-pushed the fix/voice-speaking-listener-cleanup branch from 3635da7 to ce16f0c Compare February 24, 2026 10:55
steipete added a commit that referenced this pull request Feb 25, 2026
Reimplements and consolidates related work:
- #24339 stale disconnect/destroyed session guards
- #25312 voice listener cleanup on stop
- #23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
@steipete
Copy link
Copy Markdown
Contributor

Superseded by landed commit 9cd50c51b04742f97f46ebd82ab13be6c944066a on main (via #25909).

This PR's core intent was incorporated in the consolidated Discord voice reliability landing:

  • dependency/runtime DAVE fix (@snazzah/davey restore)
  • stale-session lifecycle guards
  • listener cleanup on disconnect/leave
  • plus added DAVE config passthrough + decrypt-failure recovery + regression tests

Thanks for the original patch and direction here.

@steipete steipete closed this Feb 25, 2026
gavinwxx-vybers added a commit to Vybers-AI/openclaw that referenced this pull request Feb 25, 2026
* ui: block svg data image opens and harden tests

* changelog: credit both chat-image fix contributors

* test(ui): reject base64 SVG data URLs

* changelog: include openclaw#25847 in chat image safety entry (openclaw#25847) (thanks @shakkernerd)

* refactor(ios): drop legacy talk payload and keychain fallbacks

* chore: sync plugin versions to 2026.2.24

* chore: refresh lockfile after plugin devDependency cleanup

* fix(config): soften antigravity removal fallout (openclaw#25538)

Land openclaw#25538 by @chilu18 to keep legacy google-antigravity-auth config entries non-fatal after removal (see openclaw#25862).

Co-authored-by: chilu18 <[email protected]>

* fix(security): lock sandbox tmp media paths to openclaw roots

* docs(security): document openclaw temp-folder boundary

* fix(security): restrict default safe-bin trusted dirs

* fix: enforce local media root checks for attachment hydration

* fix(synology-chat): fail closed empty allowlist

* docs(changelog): add synology-chat allowlist fail-closed note

* fix: harden routing/session isolation for followups and heartbeat

* feat(sandbox): block container namespace joins by default

* refactor(sandbox): centralize network mode policy helpers

* fix(channels,sandbox): land hard breakage cluster from reviewed PR bases

Lands reviewed fixes based on openclaw#25839 (@pewallin), openclaw#25841 (@joshjhall), and openclaw#25737/@25713 (@DennisGoldfinger/@peteragility), with additional hardening + regression tests for queue cleanup and shell script safety.

Fixes openclaw#25836
Fixes openclaw#25840
Fixes openclaw#25824
Fixes openclaw#25868

Co-authored-by: Peter Wallin <[email protected]>
Co-authored-by: Joshua Hall <[email protected]>
Co-authored-by: Dennis Goldfinger <[email protected]>
Co-authored-by: peteragility <[email protected]>

* refactor(synology-chat): centralize DM auth and fail fast startup

* test: add routing/session isolation edge-case regressions

* refactor: centralize followup origin routing helpers

* refactor(outbound): centralize attachment media policy

* refactor: harden safe-bin trusted dir diagnostics

* fix(zalo): enforce group sender policy in groups

* docs: update changelog for safe-bin hardening

* test(line): align tmp-root expectation after sandbox hardening

* fix(web-search): reduce provider auto-detect log noise

* test(matrix,discord,sandbox): expand breakage regression coverage

* refactor(matrix,tests): extract helpers and inject send-queue timing

* refactor(zalo): split monitor access and webhook logic

* Gateway/Security: protect /api/channels plugin root

* fix(telegram): block unauthorized DM media downloads

* Security: sanitize inherited host exec env

* Changelog: add entry for exec env sanitization

* fix(security): classify hook sessions case-insensitively

* refactor(outbound): unify attachment hydration flow

* refactor(telegram): simplify DM media auth precheck flow

* fix(automation): harden announce delivery + cron coding profile (openclaw#25813 openclaw#25821 openclaw#25822)

Co-authored-by: Shawn <[email protected]>
Co-authored-by: 不做了睡大觉 <[email protected]>
Co-authored-by: Marcus Widing <[email protected]>

* security(voice-call): detect Telnyx webhook replay

* Auto-reply: add exact stop trigger for do not do that

* Auto-reply tests: assert exact do not do that behavior

* Gateway tests: cover exact do not do that stop matching

* Telegram tests: route exact do not do that to control lane

* Changelog: note exact do not do that stop trigger

* refactor(tmp): harden temp boundary guardrails

* fix(whatsapp): stop retry loop on non-retryable 440 close

* test(types): fix ts narrowing regressions in followup and matrix queue tests

* fix(onboard): avoid false 'telegram plugin not available' block

* fix: normalize "bedrock" provider ID to "amazon-bedrock"

Add "bedrock" and "aws-bedrock" as aliases for the canonical
"amazon-bedrock" provider ID in normalizeProviderId().

Without this mapping, configuring a model as "bedrock/..." causes
the auth resolution fallback to miss the Bedrock-specific AWS SDK
path, since the fallback check requires normalized === "amazon-bedrock".
This primarily affects the main agent when the explicit auth override
is not preserved through config merging.

Fixes openclaw#15716

* docs(changelog): backfill landed fix PR entries

* fix(security): harden system.run companion command binding

* fix(discord): land proxy/media/reaction/model-picker regressions

Reimplements core Discord fixes from openclaw#25277 openclaw#25523 openclaw#25575 openclaw#25588 openclaw#25731 with expanded tests.

- thread proxy-aware fetch into inbound attachment/sticker downloads
- fetch /gateway/bot via proxy dispatcher before ws connect
- wire statusReactions emojis/timing overrides into controller
- compact model-picker custom_id keys with backward-compatible parsing

Co-authored-by: openperf <[email protected]>
Co-authored-by: chilu18 <[email protected]>
Co-authored-by: Yipsh <[email protected]>
Co-authored-by: lbo728 <[email protected]>
Co-authored-by: s1korrrr <[email protected]>

* docs(changelog): add reporter credit for exec companion hardening

* fix(macos): guard voice audio paths with no input device (openclaw#25817)

Co-authored-by: Stefan Förster <[email protected]>

* fix(macos): prefer openclaw binary while keeping pnpm fallback (openclaw#25512)

Co-authored-by: Peter Machona <[email protected]>

* Auth: bypass cooldown tracking for OpenRouter

* Auth: use cooldown helper in explicit profile order

* Tests: cover OpenRouter cooldown display bypass

* Tests: skip OpenRouter failure cooldown persistence

* Tests: keep OpenRouter runnable with legacy cooldown markers

* Tests: preserve OpenRouter explicit auth order under cooldown fields

* Changelog: note OpenRouter cooldown bypass

* Changelog: remove unrelated session entries from PR

* Update CHANGELOG.md

* fix(macos): default voice wake forwarding to webchat (openclaw#25440)

Co-authored-by: Peter Machona <[email protected]>

* fix(macos): keep Return for IME marked text commit (openclaw#25178)

Co-authored-by: jft0m <[email protected]>

* fix(security): block env depth-overflow approval bypass

* fix(macos): resolve webchat panel corner clipping (openclaw#22458)

Co-authored-by: apethree <[email protected]>
Co-authored-by: agisilaos <[email protected]>

* Agents: trust explicit allowlist refs beyond catalog

* Tests: cover allowlist refs missing from catalog

* Gateway tests: accept allowlisted refs absent from catalog

* Gateway tests: include synthetic allowlist models in models.list

* Changelog: note allowlist stale-catalog model selection fix

* fix(discord): harden voice DAVE receive reliability (openclaw#25861)

Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>

* fix(macos): clean warnings and harden gateway/talk config parsing

* docs(discord): document DAVE defaults and decrypt recovery

* test: bridge discord voice private casts via unknown

* docs(changelog): remove next-release shipping sentence

* refactor(exec): split system.run phases and align ts/swift validator contracts

* fix(windows): skip unreliable dev comparison in fs-safe openVerifiedLocalFile

On Windows, device IDs (dev) returned by handle.stat() and fs.lstat()
may differ even for the same file, causing false-positive 'path-mismatch'
errors when reading local media files.

This fix introduces a statsMatch() helper that:
- Always compares inode (ino) values
- Skips device ID (dev) comparison on Windows where it's unreliable
- Maintains full comparison on Unix platforms

Fixes openclaw#25699

* fix: align windows safe-open file identity checks

* refactor: dedupe exec wrapper denial plan and test setup

* fix: harden iMessage echo dedupe and reasoning suppression (openclaw#25897)

* test(media): add win32 dev=0 local media regression

* refactor: extract iMessage echo cache and unify suppression guards

* test: normalize tmp media path assertion for windows

* fix(render): seed Control UI origin config on first boot

The gateway requires controlUi.allowedOrigins when binding to LAN.
On Render, the persistent disk starts empty with no openclaw.json.
Seed a minimal config with dangerouslyAllowHostHeaderOriginFallback
on first boot (safe behind Render's HTTPS reverse proxy).

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* chore(deps): update dependencies except carbon

* fix(agents): normalize SiliconFlow Pro thinking=off payload (openclaw#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <[email protected]>

* fix(telegram): refresh global undici dispatcher for autoSelectFamily (openclaw#25682)

Land PR openclaw#25682 from @lairtonlelis after maintainer rework:
track dispatcher updates when network decision changes to avoid stale global fetch behavior.

Co-authored-by: Ailton <[email protected]>

* fix(synology-chat): land @bmendonca3 fail-closed allowlist follow-up (openclaw#25827)

Carry fail-closed empty-allowlist guard clarity and changelog attribution for PR openclaw#25827.

Co-authored-by: Brian Mendonca <[email protected]>

* fix(agents): reduce billing false positives on long text (openclaw#25680)

Land PR openclaw#25680 from @lairtonlelis.
Retain explicit status/code/http 402 detection for oversized structured payloads.

Co-authored-by: Ailton <[email protected]>

* fix(render): add docker entrypoint script for config seeding

The inline shell command in render.yaml's dockerCommand wasn't
reliably creating the seed config. Replace with a proper entrypoint
script that creates a minimal openclaw.json with
dangerouslyAllowHostHeaderOriginFallback on first boot, then starts
the gateway bound to LAN on the PORT env var.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(ui): inherit default model fallbacks in agents overview (openclaw#25729)

Land PR openclaw#25729 from @Suko.
Use shared fallback-resolution helper and add regression coverage for default, override, and explicit-empty cases.

Co-authored-by: suko <[email protected]>

* fix(heartbeat): default target none and internalize relay prompts

* test(windows): normalize risky-path assertions

---------

Co-authored-by: Shakker <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: chilu18 <[email protected]>
Co-authored-by: Peter Wallin <[email protected]>
Co-authored-by: Joshua Hall <[email protected]>
Co-authored-by: Dennis Goldfinger <[email protected]>
Co-authored-by: peteragility <[email protected]>
Co-authored-by: Brian Mendonca <[email protected]>
Co-authored-by: Shawn <[email protected]>
Co-authored-by: 不做了睡大觉 <[email protected]>
Co-authored-by: Marcus Widing <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Mark Musson <[email protected]>
Co-authored-by: suko <[email protected]>
Co-authored-by: Fred White <[email protected]>
Co-authored-by: openperf <[email protected]>
Co-authored-by: chilu18 <[email protected]>
Co-authored-by: Yipsh <[email protected]>
Co-authored-by: lbo728 <[email protected]>
Co-authored-by: s1korrrr <[email protected]>
Co-authored-by: Stefan Förster <[email protected]>
Co-authored-by: Peter Machona <[email protected]>
Co-authored-by: jft0m <[email protected]>
Co-authored-by: apethree <[email protected]>
Co-authored-by: agisilaos <[email protected]>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
Co-authored-by: Gavin X. Wang <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: codez <[email protected]>
Co-authored-by: Ailton <[email protected]>
joshavant pushed a commit that referenced this pull request Feb 25, 2026
Reimplements and consolidates related work:
- #24339 stale disconnect/destroyed session guards
- #25312 voice listener cleanup on stop
- #23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
margulans pushed a commit to margulans/Neiron-AI-assistant that referenced this pull request Feb 25, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
Jackson3195 pushed a commit to Jackson3195/openclaw-with-a-personal-touch that referenced this pull request Feb 25, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
kevinWangSheng pushed a commit to kevinWangSheng/openclaw that referenced this pull request Feb 26, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
kevinWangSheng pushed a commit to kevinWangSheng/openclaw that referenced this pull request Feb 26, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
brianleach pushed a commit to brianleach/openclaw that referenced this pull request Feb 26, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
(cherry picked from commit 9cd50c5)

# Conflicts:
#	CHANGELOG.md
#	docs/gateway/configuration-reference.md
#	src/config/schema.labels.ts
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
(cherry picked from commit 9cd50c5)

# Conflicts:
#	CHANGELOG.md
#	docs/gateway/configuration-reference.md
#	src/config/schema.labels.ts
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: Do Cao Hieu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants