Summary
FluidVoice 1.5.13 crashes deterministically with EXC_BREAKPOINT (brk #1, Swift fatal-error trap) on the TypingService.PasteboardRestore dispatch queue. I've reproduced it 5 times across 3 sessions, all identical signatures.
The same crash hits both Clipboard Paste and Clipboard Free Insert modes, because the keystroke path falls back to insertTextViaClipboard at Sources/Fluid/Services/TypingService.swift:368 when CGEvent + Accessibility both fail β so toggling the setting is not a workaround.
Environment
- FluidVoice 1.5.13 (build 10), installed from official
.dmg
- macOS 26.3.1 (25D771280a)
- Mac14,7 (Apple Silicon)
Crash signature (5/5 reports identical)
exception : EXC_BREAKPOINT (SIGTRAP)
ESR : (Breakpoint) brk 1
queue : TypingService.PasteboardRestore
Faulting frames (binary is stripped, so only offsets resolve):
0x100124b78 (in FluidVoice) + 1576 β PC, brk #1
0x100124390 (in FluidVoice) + 64
0x100105bb8 (in FluidVoice) + 28
_dispatch_call_block_and_release
_dispatch_lane_serial_drain
...
+1576 places the trap deep inside a substantial function. By elimination via code audit (below), that function is almost certainly waitForFocusedTextVerification.
Audit β what runs on pasteboardRestoreQueue
The closure at TypingService.swift:553 only calls:
waitForFocusedTextVerification
NSPasteboard accessors (cannot brk #1)
restorePasteboardSnapshot (no force-unwraps, no subscripts)
log
brk #1 candidates inside waitForFocusedTextVerification (lines ~937β1000):
| Line(s) |
Code |
Risk |
| 973, 991 |
before.location + expectedLength |
High β overflows if AX returns NSNotFound (= Int.max) for selected-range location |
| 974, 992 |
abs(after.location - expectedCaretLocation) |
High β same root cause |
No force-unwraps, as! casts, or array subscripts on this path. The integer-overflow hypothesis is the only viable explanation in the file.
Why Clipboard Free Insert doesn't avoid it
TypingService.swift:368 β when CGEvent + Accessibility both fail (common against stubborn Electron / GPU-terminal / web targets), the pipeline falls through to insertTextViaClipboard, which dispatches onto pasteboardRestoreQueue and re-enters the same trap.
// Fallback: Use clipboard-based insertion (more reliable)
self.log("[TypingService] CGEvent failed, trying clipboard fallback")
if self.insertTextViaClipboard(text) { ... } // β re-enters the buggy queue
Suggested fix
Guard the arithmetic in waitForFocusedTextVerification against NSNotFound/overflow before using before.location:
// In both the `appScriptSelectedRange` and `selectedRange` branches:
guard before.location != NSNotFound,
after.location != NSNotFound,
after.length == 0
else { /* skip this signal, keep polling */ }
let (expectedCaretLocation, addOverflow) =
before.location.addingReportingOverflow(expectedLength)
guard !addOverflow else { continue }
let (rawDelta, subOverflow) =
after.location.subtractingReportingOverflow(expectedCaretLocation)
guard !subOverflow else { continue }
let caretDelta = abs(rawDelta)
A defense-in-depth alternative is to sanitize at the source in getSelectedTextRange β return nil if range.location == NSNotFound or range.location < 0. That also protects any future callers.
What I'd need to be 100% sure of the line
The shipped binary is fully stripped (nm shows imported symbols only), and no dSYM is published with the v1.5.13 release. The atos output above is the best I can recover from outside.
Could you either:
- Attach
Fluid-oss-1.5.13.dSYM.zip to the v1.5.13 GitHub release, or
- Paste the output of:
atos -arch arm64 -o /path/to/FluidVoice.app/Contents/MacOS/FluidVoice -l <load-addr> 0x101000b78
from a build that has symbols.
That pins the exact line, and I'll send a PR.
Crash report
Available on request β .ips files contain hardware identifiers I'd rather not paste publicly. Happy to share via a private channel.
Summary
FluidVoice 1.5.13 crashes deterministically with
EXC_BREAKPOINT(brk #1, Swift fatal-error trap) on theTypingService.PasteboardRestoredispatch queue. I've reproduced it 5 times across 3 sessions, all identical signatures.The same crash hits both
Clipboard PasteandClipboard Free Insertmodes, because the keystroke path falls back toinsertTextViaClipboardatSources/Fluid/Services/TypingService.swift:368when CGEvent + Accessibility both fail β so toggling the setting is not a workaround.Environment
.dmgCrash signature (5/5 reports identical)
Faulting frames (binary is stripped, so only offsets resolve):
+1576places the trap deep inside a substantial function. By elimination via code audit (below), that function is almost certainlywaitForFocusedTextVerification.Audit β what runs on
pasteboardRestoreQueueThe closure at
TypingService.swift:553only calls:waitForFocusedTextVerificationNSPasteboardaccessors (cannotbrk #1)restorePasteboardSnapshot(no force-unwraps, no subscripts)logbrk #1candidates insidewaitForFocusedTextVerification(lines ~937β1000):before.location + expectedLengthNSNotFound(=Int.max) for selected-range locationabs(after.location - expectedCaretLocation)No force-unwraps,
as!casts, or array subscripts on this path. The integer-overflow hypothesis is the only viable explanation in the file.Why
Clipboard Free Insertdoesn't avoid itTypingService.swift:368β when CGEvent + Accessibility both fail (common against stubborn Electron / GPU-terminal / web targets), the pipeline falls through toinsertTextViaClipboard, which dispatches ontopasteboardRestoreQueueand re-enters the same trap.Suggested fix
Guard the arithmetic in
waitForFocusedTextVerificationagainstNSNotFound/overflow before usingbefore.location:A defense-in-depth alternative is to sanitize at the source in
getSelectedTextRangeβ returnnilifrange.location == NSNotFoundorrange.location < 0. That also protects any future callers.What I'd need to be 100% sure of the line
The shipped binary is fully stripped (
nmshows imported symbols only), and no dSYM is published with the v1.5.13 release. The atos output above is the best I can recover from outside.Could you either:
Fluid-oss-1.5.13.dSYM.zipto the v1.5.13 GitHub release, orThat pins the exact line, and I'll send a PR.
Crash report
Available on request β
.ipsfiles contain hardware identifiers I'd rather not paste publicly. Happy to share via a private channel.