Skip to content

Comments

fix(macos): prevent crash from missing ClawdbotKit resources and Swift 6.2 library#473

Merged
steipete merged 1 commit intoopenclaw:mainfrom
gupsammy:fix/macos-app-crash-bundle-resources
Jan 8, 2026
Merged

fix(macos): prevent crash from missing ClawdbotKit resources and Swift 6.2 library#473
steipete merged 1 commit intoopenclaw:mainfrom
gupsammy:fix/macos-app-crash-bundle-resources

Conversation

@gupsammy
Copy link
Contributor

@gupsammy gupsammy commented Jan 8, 2026

Summary

Fixes two related crashes in the macOS menu bar app:

Problem

Crash 1: Bundle.module assertion failure (#213)

After running for 40-80 minutes, when the first tool event arrived through ControlChannel, ToolDisplayRegistry.resolve() tried to load config via ClawdbotKitResources.bundle. This used Bundle.module directly, which in packaged .app bundles couldn't find the resource bundle at the expected SwiftPM path, causing a fatal assertion:

_assertionFailure → closure #1 in variable initialization expression of static NSBundle.module
→ ToolDisplayRegistry.resolve → WorkActivityStore.handleTool → ControlChannel

Crash 2: dyld library not loaded (#417)

Swift 6.2 on macOS 26 requires libswiftCompatibilitySpan.dylib, but SwiftPM doesn't bundle it automatically. This caused immediate crash on launch:

dyld: Library not loaded: @rpath/libswiftCompatibilitySpan.dylib

Solution

  1. ClawdbotKitResources.swift: Replace direct Bundle.module access with a safe bundle locator that:

    • Checks Bundle.main/Resources/ClawdbotKit_ClawdbotKit.bundle first (packaged apps)
    • Falls back to manual bundle search (avoids Bundle.module's fatalError)
    • Returns Bundle.main as final fallback (resource lookups return nil gracefully)
  2. package-mac-app.sh:

    • Copy ClawdbotKit_ClawdbotKit.bundle to app's Resources folder
    • Copy libswiftCompatibilitySpan.dylib from Xcode toolchain to Frameworks folder

Test Plan

  • Built and packaged app with scripts/package-mac-app.sh
  • Verified ClawdbotKit_ClawdbotKit.bundle present in /Applications/Clawdbot.app/Contents/Resources/
  • Verified libswiftCompatibilitySpan.dylib present in /Applications/Clawdbot.app/Contents/Frameworks/
  • App launches without dyld crash
  • App runs without Bundle.module crash when tool events arrive
  • ClawdbotKit tests pass (swift test in ClawdbotKit package)

AI Assistance Disclosure

🤖 This PR was developed with Claude Opus 4.5 assistance:

  • Testing level: Fully tested on macOS 26.2 with Swift 6.2
  • Understanding: I understand what the code does - it's a safe bundle locator pattern similar to what's already used in DeviceModelCatalog.swift

🦞 Generated with Claude Code

…t library

The macOS app was crashing in two scenarios:

1. Bundle.module crash (fixes openclaw#213): When the first tool event arrived,
   ToolDisplayRegistry tried to load config via ClawdbotKitResources.bundle,
   which used Bundle.module directly. In packaged apps, Bundle.module
   couldn't find the resource bundle at the expected path, causing a
   fatal assertion failure after ~40-80 minutes of runtime.

2. dyld crash (fixes openclaw#417): Swift 6.2 requires libswiftCompatibilitySpan.dylib
   but SwiftPM doesn't bundle it automatically, causing immediate crash on
   launch with "Library not loaded" error.

Changes:
- ClawdbotKitResources.swift: Replace direct Bundle.module access with a
  safe locator that checks multiple paths and falls back gracefully
- package-mac-app.sh: Copy ClawdbotKit_ClawdbotKit.bundle to Resources
- package-mac-app.sh: Copy libswiftCompatibilitySpan.dylib from Xcode
  toolchain to Frameworks

Tested on macOS 26.2 with Swift 6.2 - app launches and runs without crashes.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@gupsammy
Copy link
Contributor Author

gupsammy commented Jan 8, 2026

CI Failure Note

The Node.js CI checks are failing, but this is a pre-existing issue on main branch unrelated to this PR.

Root cause: pnpm-lock.yaml is out of sync with package.json - the lockfile is missing the markdown-it dependency:

ERR_PNPM_OUTDATED_LOCKFILE: Cannot install with "frozen-lockfile" because 
pnpm-lock.yaml is not up to date with package.json

Failure reason: "markdown-it":"^14.1.0" is in package.json but not in lockfile

Evidence: The last 3 commits on main also failed CI with the same error:

  • a851444a - chore: expand provider details in status → ❌ failed
  • 840c6408 - docs: refresh daemon troubleshooting guidance → ❌ failed
  • fa501e77 - test: force bun fetch path in telegram send → ❌ failed

This PR's relevant checks passed:

  • macos-app (lint) - swiftlint + swiftformat
  • macos-app (test) - swift test

The lockfile sync issue needs to be addressed separately by running pnpm install and committing the updated lockfile.

@steipete
Copy link
Contributor

steipete commented Jan 8, 2026

Thanks Samarth! Welcome to the Clawtributors! Say hi on Discord!

@steipete
Copy link
Contributor

steipete commented Jan 8, 2026

Landed on main.\n\n- Rebased onto latest main, fast-forwarded landing branch.\n- Added ToolDisplayRegistry bundle test and changelog entry.\n- Ran pnpm lint && pnpm build && pnpm test.\n\nSHAs: 29e9a57 (PR), f1bc178 (landing commit).\n\nThanks @gupsammy!

@steipete steipete closed this Jan 8, 2026
@steipete steipete reopened this Jan 8, 2026
@steipete steipete merged commit 491f928 into openclaw:main Jan 8, 2026
22 of 34 checks passed
ashiabbott pushed a commit to ashiabbott/openclaw that referenced this pull request Feb 20, 2026
The upstream test used a bare Telegram chat ID ('123456') as the send
target, which fails at resolveActionTarget — Telegram targets require a
directory entry or special bypass. This made the regression test for
mediaLocalRoots threading permanently broken.

Replace with a spy plugin registered on the 'imessage' channel, where
phone-number targets (+15551234567) bypass directory lookup via the
special /^\+\?\d{6,}\$/ path in resolveMessagingTarget. The spy plugin
captures ctx.mediaLocalRoots from handleAction and we assert it contains
the agent workspace directory, verifying the fix in
outbound-send-service.ts (getAgentScopedMediaLocalRoots threading).

Fixes: broken regression test for task openclaw#473 (message tool mediaLocalRoots)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants