fix(macos): guard against SIGABRT when no audio input device available#12334
fix(macos): guard against SIGABRT when no audio input device available#12334arosstale wants to merge 5 commits intoopenclaw:mainfrom
Conversation
The /reset and /new commands send a technical banner message to the channel (e.g. '✅ New session started · model: provider/model'). In group chats this leaks internal model/provider information to all participants — undesirable for professional or client-facing groups. Add !isGroupChat guard to the reset banner delivery. The variable isGroupChat is already computed earlier in the same function (line 162). DM sessions continue to receive the confirmation as before. Fixes openclaw#12155
Address Greptile review: ChatType can be 'group' or 'channel' (e.g. Slack/Discord channels). Use explicit ChatType === 'direct' check instead of !isGroupChat to cover both multi-party chat types.
Google Chat webhook events identify the bot by numeric user ID (e.g. users/112986094383820258709), not the users/app alias that works in API calls. When botUser is not configured, extractMentionInfo fails to recognize the bot is being mentioned, silently dropping all Space @mention messages while DMs work fine. Add a fallback check for userMention.user.type === "BOT" so the bot is correctly identified even without an explicit botUser config entry. Fixes openclaw#12323
On Windows, executables have extensions (.exe, .cmd, .bat, etc.) but skill requirements specify bare names like "curl" or "gh". The hasBinary function only checked for the exact name, so it never found Windows executables — reporting all skills as missing requirements despite the binaries being installed and functional. Use the PATHEXT environment variable (standard on Windows) to also check candidates with executable extensions. Falls back to ".COM;.EXE;.BAT;.CMD" if PATHEXT is not set. On non-Windows platforms the behavior is unchanged. Fixes both instances: src/agents/skills/config.ts (skills check) and src/hooks/config.ts (hooks check). Fixes openclaw#12288
Accessing AVAudioEngine.inputNode when no microphone is connected causes an immediate SIGABRT crash, creating a crash loop on Mac Mini and other mic-less Macs. Add AVCaptureDevice.default(for: .audio) != nil guard before accessing inputNode in all 5 audio-tap sites: - VoiceWakeRuntime.swift (voice wake listener) - VoiceWakeTester.swift (settings test view) - MicLevelMonitor.swift (mic level indicator) - TalkModeRuntime.swift (talk mode) - VoicePushToTalk.swift (push-to-talk) When no audio device is available, the functions now return early with a warning log instead of crashing. Fixes openclaw#12169
Additional Comments (2)
Prompt To Fix With AIThis is a comment left during a code review.
Path: extensions/googlechat/src/monitor.ts
Line: 378:396
Comment:
**Bot mention mis-detection**
`extractMentionInfo` now treats any `USER_MENTION` whose `user.type` is `BOT` as a mention of *this* bot (`return entry.userMention?.user?.type?.toUpperCase() === "BOT"`). In group chats where someone mentions a different bot, `wasMentioned` will become true and bypass `requireMention` gating, causing the integration to respond when it shouldn’t. Consider scoping this check to the actual bot identity (e.g., compare against `botUser`/known bot user id) rather than any BOT type mention.
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/macos/Sources/OpenClaw/VoiceWakeTester.swift
Line: 81:97
Comment:
**NSError code collision**
`VoiceWakeTester.start` throws `NSError(domain: "VoiceWakeTester", code: 2, ...)` for both permission denial (`"Microphone or speech permission denied"`) and the new “no audio input device available” case. If UI/callers branch on `error.code`, these two distinct failures will be conflated. Using a distinct code for the no-device path (or a typed error) avoids misreporting the failure reason.
How can I resolve this? If you propose a fix, please make it concise. |
Summary
Prevents SIGABRT crash loop on Macs without a microphone (Mac Mini, headless, disconnected Bluetooth audio).
Fixes #12169
Problem
Accessing
AVAudioEngine.inputNodewhen no audio input device is connected causes an immediate SIGABRT. The app crash-loops (7 crashes in 7 minutes reported in the issue) because voice wake restarts on launch.Fix
Add
AVCaptureDevice.default(for: .audio) != nilguard before accessinginputNodein all 5 audio-tap sites:VoiceWakeRuntime.swiftVoiceWakeTester.swiftMicLevelMonitor.swiftTalkModeRuntime.swiftVoicePushToTalk.swiftWhen no audio device is available, functions return early with a warning log instead of crashing. Normal behavior when a mic IS available is unchanged.
Greptile Overview
Greptile Summary
This PR adds guards on macOS audio capture/tap sites to avoid accessing
AVAudioEngine.inputNodewhen no audio input device is available (which can SIGABRT and cause a crash loop on mic-less Macs). It also includes a few unrelated fixes: WindowshasBinarynow respectsPATHEXT, Google Chat webhook mention detection is expanded, and the reset banner routing is tightened.Key issues to address before merge:
requireMentionand triggering replies in group spaces unexpectedly.Confidence Score: 4/5