Bug/Crash: Qt Accessibillity / QAccessibleCache

Hi! If this is not the right place to post this, let me know and I’ll post it to the relevant place :slight_smile:

Subject: Crash on Subsequent File Opening with Accessibility / UI Element Attribute Fetching or Polling (QAccessibleCache)

SpectraLayers Version: 12.0.40.433
macOS Version: 15.7.3 (24G419) ← seems to have started with this build?
Hardware: MacBook Pro M1 Max

Problem: SpectraLayers crashes consistently when opening a second file after closing the first, but only when SoundFlow (third-party automation software) has previously fetched or polled accessibility elements / UI element accessibility attributes

Steps to Reproduce:

  1. Open SpectraLayers 12

  2. Open an audio file → works fine

  3. Use a SoundFlow script that fetches or polls element attributes (.exists, .isEnabled, isMenuChecked, etc)

  4. Close the file

  5. Open a second audio file → crash

Does NOT crash when:

  • SoundFlow is not used to fetch / poll element attributes

Technical Details: The crash occurs in SpectraLayers’ Qt accessibility system during UI updates:
Thread 0 Crashed (main thread): objc_msgSend + 32 QAccessibleCache::removeAccessibleElement(unsigned int) + 144QAccessibleCache::deleteInterface(unsigned int, QObject*) + 516QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent*) + 1244 → Triggered by QListModel::clear() during tab switching Exception: EXC_BAD_ACCESS (SIGSEGV) Invalid memory address: 0x000059191f50fa60

OK it’s probably on my end but I found the exact instability: mapping the title value of the AxCell element(s) in the undo history panel. Filtering first by role of AXStaticText seems to solve the issue.

here’s the function in question:

function getUndoHistoryLengthAndLastItem() {
    const undoPanel = sf.ui.app("com.Steinberg.SpectraLayers12").mainWindow.children.whoseRole.is("AXList").allItems[5];
    const undoItems = undoPanel.children.whoseRole.is("AXRow").allItems;

    const undoItemTitleValues = undoItems.filter(x => x.children.first.role == "AXStaticText")
        .map(item => item.children.first.title.value);
    //end undoItemTitleValues

    const historyLength = undoItemTitleValues.length
    const lastItemIsUnmixNoisySpeech = undoItemTitleValues.slice(-1)[0] == "Unmix Noisy Speech event. Moving up or down undo or redo actions."
    return { historyLength, lastItemIsUnmixNoisySpeech }
}

If I use this it crashes on next file open:
const undoItemTitleValues = undoItems.map(item => item.children.first.title.value);

if I use this, it seems to be fine:
const undoItemTitleValues = undoItems.filter(x => x.children.first.role == "AXStaticText").map(item => item.children.first.title.value);