Skip to content

Libre 3+ native glucose Critical Alerts ignore configured alert sound and always use iOS default Critical Alert sound #2481

Open

Description

@Shuengr

Description
Environment
Loop: next-dev
Built via: GitHub Browser Build (Fastlane)
Branch updated: Current next-dev (built current commits as of July 31, 2026 12:11CDT)
iPhone 17 Pro Max
iOS 26.4.2
Omnipod 5
Libre 3+ native BLE support

Summary

With the new native Libre glucose alerts in next-dev, the configured glucose alert sound is ignored.

The alert is delivered as an iOS Critical Alert, but it always plays the system default Critical Alert sound (Radial on my device) rather than the sound selected in Loop.

Steps to reproduce
Build the latest next-dev.
Configure a custom sound for Critical Low (or High) glucose alerts in Loop (for example Urgent Low).
Verify the sound preview in the settings screen.
Trigger either:
a real glucose low, or
Loop's "next reading as low" test.
Observe the alert sound.

Expected behavior
The glucose alert should use the sound selected in Loop (for example "Urgent Low").

Actual behavior
The notification is delivered as a Critical Alert, but always plays the iOS default Critical Alert sound (Radial).

This occurs for both:
simulated/test glucose alerts
actual glucose low alerts

Additional observations
Critical Alerts are enabled in iOS.
Notifications correctly bypass Silent Mode and Focus.
The selected sound previews correctly inside Loop.
Changing the selected sound has no effect on actual glucose alerts.
Rebuilding from the latest next-dev does not change the behavior.

Investigation
While debugging this locally, I noticed that Libre glucose notifications appear to be generated by:

LibreTransmitter/NotificationHelper.swift

Within NotificationHelper.addRequest(...), critical alerts always assign:

content.sound = .defaultCriticalSound(withAudioVolume: ...)

rather than a named critical sound.

Because of this, it appears that the configured glucose alert sound is never used for Libre glucose alerts.

The notification is correctly marked:

content.interruptionLevel = .critical

but the sound is always assigned via:

.defaultCriticalSound(...)

instead of a user-selected sound.

I wasn't sure if this is intentional while the new Libre alert implementation is under development, or if it's an oversight. I'm happy to test a fix or provide additional information if helpful.

One additional note, while reviewing the code, I also noticed:

Float(criticalVolume / 100)

If criticalVolume is an integer, values between 60–99 would evaluate to 0 before conversion. I'm not sure of the type of mmCriticalAlarmsVolume, so this may or may not be an issue, but it caught my eye during review.

Loop Report 2026-08-01 22_22_25-05_00.md

Activity

  1. dabear commented on Aug 2, 2026

    @dabear
    Contributor

    In next-dev if you are using Libre 3+ you are not using any libretransmitter code. That would be the new libreloop plugin

  2. Shuengr commented on Aug 3, 2026

    @Shuengr
    Author

    The next-dev LibreLoop readme file states 'Alerting is handled entirely by Loop'. The activity I observe looks like what I referenced where critical alerts are pointed to the default iOS sound.

  3. ps2 commented on Sep 16, 2026

    @ps2
    Collaborator

    Tracked this down — it's real, but not in LibreTransmitter and not in the notification path either. Fix in #2520.

    @dabear is right that Libre 3+ on next-dev never touches LibreTransmitter. Those alarms come from Loop's own GlucoseAlertManager, and it does stamp your selected sound onto the alert. The notification path honours it too — UserNotificationAlertScheduler requests criticalSoundNamed for the copy Loop puts in Library/Sounds. If that were what was making the sound, you'd hear your selection.

    The catch is in your Loop Report: criticalAlertsEnabled: false. Builds without the Critical Alerts entitlement — every DIY / Browser Build — don't raise urgent lows as an iOS Critical Alert at all. On iOS 26 AlertManager raises them through AlarmKit instead, and that alarm was being scheduled with no sound:

    // Default alarm sound (our .caf alarm sounds aren't guaranteed AlarmKit-compatible).

    AlarmKit's default tone is "Radial". An AlarmKit alarm breaks through Silent and Focus, so it looks exactly like a Critical Alert, but it has its own sound configuration that the Loop setting never reached. That's why changing the selection did nothing and the preview (which plays the file directly) still worked.

    #2520 passes the configured sound to AlarmKit by name. The bundled sounds are all IMA4 .caf under 30 s, which is the same constraint a notification sound has, so they qualify.

    On your second note — Float(criticalVolume / 100) doesn't exist in next-dev's LibreTransmitter (no matches anywhere in the tree), so I think you were reading a different branch. Either way it can't affect Libre 3+.

  4. ps2 commented on Sep 16, 2026

    @ps2
    Collaborator

    Correction to my comment above: the AlarmKit alarm wasn't what you were hearing, because it has never run for you. Authorization is only requested during onboarding, so anyone onboarded before that step existed is still .notDetermined and the scheduler bails. What plays "Radial" is the downgraded criticalSoundNamed notification — iOS won't honour the critical flag without the entitlement and falls back to the system default alert tone.

    #2520 is reworked: it now requests AlarmKit authorization at launch for already-onboarded users (expect a one-time system prompt), passes your configured sound to the alarm, and fixes a separate bug where a CGM backfill retracted an urgent-low alert a second after it fired. With those, the audible channel on your build becomes the AlarmKit alarm with your chosen sound.

  5. ps2 commented on Sep 16, 2026

    @ps2
    Collaborator

    One more correction, and then I'll stop revising: authorization is requested both during onboarding and on every launch (since the June AlarmKit work), and both are no-ops once decided. So if you've never seen a prompt, the decision was already made on an earlier launch — and if AlarmKit isn't allowed, the alarm never fires and all you get is the downgraded notification with the system default tone.

    Please check Settings → Loop → Allow Alarms. If it's off, turning it on should make the next urgent low fire as an AlarmKit alarm; with #2520 it will play your selected sound rather than the default.

  6. ps2 commented on Sep 16, 2026

    @ps2
    Collaborator

    Confirmed on hardware with #2520: on a DIY build without the entitlement, with Alarms allowed, an urgent low now fires as an AlarmKit alarm playing the sound selected in Loop, and it persists until stopped.

    If you're still hearing the default tone after that lands, check Settings → Loop → Allow Alarms — #2520 also adds an Alarms row under Alert Management → iOS Permissions so that state is visible in-app, alongside a Critical Alerts: Not Available row and a link to instructions for requesting the entitlement from Apple.

  7. Shuengr commented on Sep 27, 2026

    @Shuengr
    Author

    @ps2 The urgent low alerts appear to be mostly working with the defined sound now.

    I have noticed that predicted low alerts are still not generating any audible alerts, there are the loop app popup boxes but no sounds.

    I also noticed a specific scenario today where no audible alert was played for an urgent low.

    I had just silenced an urgent low, and was treating, Got into my truck and connected (wired) to my truck's (ford sync3) carplay. I was listening to an apple podcasts show, my phone was wired to carplay. I did not get the audible alarm. A few +5 minutes after the last reading I received a text message and looked down at my phone. The minimized urgent low alarm (alarmkit) was still at the top of my screen and active. I will attach a loop report. that should cover both the lack of predicted low audible alerts and the missing audible alert when in carplay.

    Latest Loop build 36a6c91,
    current iOS 26.7,
    iPhone 17 Pro Max,
    Ford Sync3 wired carplay

    Loop Report 2026-09-27 14_29_16-05_00.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions