Skip to content

Bonjour plugin crashes gateway in restart loop on macOS (CIAO ANNOUNCEMENT CANCELLED) #71781

@andrewtclark

Description

@andrewtclark

Bug Summary

Regression introduced ~2026.4.3–2026.4.24

Symptom

openclaw gateway crashes repeatedly with Unhandled promise rejection: CIAO ANNOUNCEMENT CANCELLED every ~34 seconds. The gateway reaches ready state but never stabilizes.

Root Cause (two parts)

  1. Stuck mDNS announcement: The CIAO mDNS announcement gets stuck in announcing state indefinitely (never transitions to announced). Likely caused by CIAO iterating over too many macOS network interfaces (19 on a typical M-series Mac — anpi, awdl, utun system tunnels, etc.) and failing to complete its multicast loopback confirmation.

  2. Unregistered rejection handler: The watchdog's recreateAdvertiser() calls svc.destroy() on the stuck service, which causes CIAO to throw ANNOUNCEMENT CANCELLED as an unhandled promise rejection. The handleCiaoUnhandledRejection function in extensions/bonjour/index.js is correctly written to suppress this, but the plugin entry point at line 287 only passes { logger: api.logger } to startGatewayBonjourAdvertiser — it never passes registerUnhandledRejectionHandler. So the suppression handler is never registered and the rejection crashes the Node process.

Environment

  • macOS (M-series Mac, 19+ network interfaces)
  • OpenClaw version: latest as of 2026-04-25

Workaround

OPENCLAW_DISABLE_BONJOUR=1

(env var check exists at line 48 of extensions/bonjour/index.js)

Important: Must be set in both .zshrc and the launchd plist EnvironmentVariables dict, since launchd doesn't inherit shell env.

Suggested Fixes

  1. Wire up the handler: Pass registerUnhandledRejectionHandler in the plugin entry call at line 287 of extensions/bonjour/index.js.
  2. Add fallback: Add a direct process.on('unhandledRejection', ...) fallback inside startGatewayBonjourAdvertiser when deps.registerUnhandledRejectionHandler is absent.
  3. Filter interfaces: Investigate filtering out non-physical/non-routable interfaces (utun, awdl, anpi, gif, stf) from CIAO's interface list to address the stuck-announcement root cause.

Metadata

Metadata

Assignees

No one assigned

    Labels

    dedupe:childDuplicate issue/PR child in dedupe clusterduplicateThis issue or pull request already exists

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions