Playbeat 4.2.2 crash when recalling Performance Keyboard states with FX bus on/off

I’ve run into a reproducible crash in Playbeat 4.2.2 inside Ableton Live 12.4 on macOS 15.6.

The crash happens when recalling saved states from Playbeat’s Performance Keyboard if the FX bus state differs between the saved states.

I was able to reproduce it in a very simple setup with essentially nothing else going on:

  1. Load Playbeat 4.2.2 in Ableton Live.
  2. Create a pattern/state with the FX bus enabled on one of the drum tracks.
  3. Save that state to a Performance Keyboard key.
  4. Create/save another state where the FX bus on that same track is switched off.
  5. Trigger the saved states from the Performance Keyboard/MIDI.
  6. Switching between the FX-on and FX-off states causes Ableton Live to crash immediately.

I was also able to reproduce the issue after originally saving a state with FX enabled, later switching the FX bus off, and then recalling the previously saved state.

The macOS crash report points directly into Playbeat during the failure. The crashed main thread shows:

juce::AudioProcessorGraph::Pimpl::handleAsyncUpdate()
juce::LockingAsyncUpdater::Impl::messageCallback()

The crash itself is an EXC_BAD_ACCESS / SIGSEGV at address 0x0.

Another thread shows Playbeat receiving the MIDI note and restoring the Performance Keyboard state immediately before the crash:

AMPerformanceManager::performNoteOn()
AMActionManager::loadSnapshot()
AMActionManager::restoreState()
AMAudioProcessorGraph::loadFromXml()
AMAudioProcessorGraph::loadParamsInSlot()
AMAudioProcessorGraph::updateGraph()
juce::AudioProcessorGraph::Pimpl::addNode()

The crash report confirms the plugin version is Playbeat 4.2.2 VST3.

Based on the stack trace and the reproduction, it appears that recalling a saved Performance Keyboard state that changes the FX bus enabled/disabled state may leave Playbeat’s internal AudioProcessorGraph in an invalid state during the asynchronous graph update.

For now I’m simply avoiding Playbeat’s internal effects entirely, which seems to be an adequate workaround for my use case.

Thanks for the detailed information. We’re on it.