BTT: a deleted trigger returns after restart if it was updated before deletion

Version: BetterTouchTool 6.706 (build 2026080706)

macOS: 27.0 beta (26A5388g), Apple M3 Max

Summary

A trigger that is created, then updated, then deleted — with the deletion confirmed by re-querying — reappears in the configuration after BetterTouchTool restarts. Without the intervening update, deletion is durable.

Observed twice, on two independent UUIDs (AB49AF7C…, ABD08A04…). A control arm run alongside it never resurrected.

Steps to reproduce

Arm A (resurrects):

  1. add_new_trigger — note the returned UUID
  2. update_trigger on that UUID (any field change)
  3. delete_trigger on that UUID
  4. Re-query get_triggers → trigger is absent. Deletion looks successful.
  5. Quit and relaunch BetterTouchTool
  6. Re-query get_triggersthe trigger is back

Arm B (control, behaves correctly):

  1. add_new_trigger
  2. delete_trigger
  3. Quit and relaunch → stays deleted

Expected

A deletion confirmed by a subsequent read should survive a restart, regardless of whether the trigger was modified beforehand.

Actual

The update appears to leave a pending write that is flushed on restart and recreates the deleted row. The in-memory view and the persisted store disagree, and the persisted store wins at launch.

Why this matters

The failure is silent and delayed. Anything doing programmatic cleanup — a test harness, a preset installer, a sync tool, a script that tidies up after itself — verifies deletion, sees success, and only discovers the resurrection after the next restart. Users editing triggers by hand can hit the same path.

It also makes "delete" untrustworthy as a rollback primitive, which is what led us to notice it: we were relying on create → verify → delete to leave a user's configuration untouched.

Possibly the same underlying issue as an existing open thread

44338 — "Triggers Linked to a Specific App like Preview will work even after Preview App is removed from the sidebar" reports triggers that keep firing while being invisible in the UI, still present in the exported preset. The reply there was "if you delete an app all triggers that belong to it are also deleted", with the suggestion it may have been hiding rather than deleting, and the thread did not conclude.

That is the same class of problem as this one: BTT's queryable view and its persisted store disagreeing, with rows surviving that the user believes are gone. If it is the same defect, what that thread was missing is a deterministic reproduction — which the two arms above provide, including a control arm that behaves correctly. Worth checking whether one fix closes both.

Suggested fix

Ensure delete_trigger invalidates or supersedes any queued write for the same UUID, so a pending update cannot re-materialize a deleted trigger at launch.

Checked for duplicates

Searched the forum before posting. The nearest match is 44338 above, cited as possibly-related rather than as a duplicate, since it concerns app-scope removal rather than explicit deletion and does not mention the update-before-delete sequence or a restart being required to expose it.

did you maybe kill BTT (or did it crash)? In general it should auto save when being terminated, but that might not be possible in all cases. I added an explicit save on deletion with 6.717