From 3c8c319f3adcfa00652b3e9830745f688a96c4c9 Mon Sep 17 00:00:00 2001 From: Tyler Hebenstreit Date: Wed, 1 Jul 2026 11:26:03 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20Fix=20crash=20when=20a=20cycle?= =?UTF-8?q?=20action=20has=20an=20empty=20cycle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `getNextCycleAction` indexes `currentCycle[0]` when restarting or when no current index is found, but only guarded against a nil `cycle`, not an empty one. A cycle action configured with zero sub-actions therefore traps (EXC_BREAKPOINT) on the empty-array subscript. Guard against an empty cycle and return the action unchanged. --- Loop/Core/LoopManager.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Loop/Core/LoopManager.swift b/Loop/Core/LoopManager.swift index 6faf7918..8025b738 100644 --- a/Loop/Core/LoopManager.swift +++ b/Loop/Core/LoopManager.swift @@ -474,7 +474,10 @@ extension LoopManager { } private func getNextCycleAction(_ action: WindowAction) async -> WindowAction { - guard let currentCycle = action.cycle else { + // An empty cycle has no actions to advance to; bail out instead of indexing + // into it — the `currentCycle[0]` accesses below would trap on an empty array + // (EXC_BREAKPOINT crash when a cycle action is configured with no sub-actions). + guard let currentCycle = action.cycle, !currentCycle.isEmpty else { return action }