Troubleshooting
What the banners mean, what to do when something looks off, and the recovery paths for the failure modes brtlb actually sees in the wild.
Diarization banner
Amber banner above the note that says one of two things, sometimes both:
"Heads up — the transcription returned fewer distinct speakers than this visit likely had."
Means AssemblyAI collapsed multiple voices into one cluster. Symptom: a parent's history-taking and a child's first-person answers end up under the same speaker label. The note may attribute the wrong person.
"Speaker B may contain more than one voice — the assistant couldn't confidently assign a single role."
Means brtlb's own analysis found register shifts within one cluster (adult clinical vocabulary mixed with child one-word answers, etc.). Often correlates with the count issue above.
What to do
- If brtlb proposes an Apply split button right there in the banner, that's the fastest fix. Tap it. brtlb renames the merged speaker (e.g.,
B→B1+B2) and seeds role chips. Click Regenerate after to get a fresh note with the new attribution. - If there's no Apply split button (recovery couldn't find a confident partition), open raw json in the top-right of the Review screen. Scan the transcript for the suspect speaker. Tag the speaker chips manually if needed, then Regenerate.
- If both fail, the cleanest fix is to re-record with the kid sitting on the parent's lap rather than across the room, or with the mic closer to the child. Same-gender voices at similar age tiers are AAI's hardest case.
Coverage banner
Amber banner that says something like:
"Heads up — the template expected 2 sections that aren't in the note: Anticipatory Guidance, Follow-up. Was any of this discussed?"
Or alternatively: "The last section ends without final punctuation — the model may have been cut off."
The first variant flags a structural gap: your template asked for sections the note doesn't contain. Sometimes that's correct (you didn't discuss them), sometimes the LLM dropped them.
The second variant flags a likely token-cap truncation — the model ran out of room and stopped mid-sentence.
What to do
- If the missing content was actually discussed: click Regenerate. Often the model picks it up on the second pass.
- If it wasn't discussed: dismiss the banner. Empty sections are not a bug; brtlb's discipline rules prefer omission to fabrication.
- If it's a truncation flag: regenerate. brtlb's output cap is 16K tokens — long visits sometimes need a second pass. If it keeps truncating, simplify your template (drop a section, switch from narrative to focused pattern).
Stuck on a stage
The Review screen shows a stage banner: uploading → transcribing → generating → ready. If it's stuck:
Stuck on "uploading"
Your connection dropped during the audio upload to AssemblyAI. brtlb auto-retries once. If it's still stuck after a minute:
- Check Wi-Fi / cellular. Switch networks if possible.
- Click Reprocess from audio (or whatever the retry button is). brtlb starts the pipeline over from the stored audio blob — no re-recording needed.
Stuck on "transcribing"
brtlb polls AssemblyAI every 5 seconds and waits up to 90 minutes. Most visits finish in 30 seconds to 5 minutes. If the bar's been spinning for >15 minutes on a normal-length recording:
- Check AssemblyAI status.
- Open the raw JSON link if available — sometimes the transcript completed but the polling lost the thread.
- Retry from audio if you have time pressure; AAI can complete the original job in the background and you'll just have two transcripts to compare.
Stuck on "generating"
Gemini (or your chosen LLM provider) is slow or struggling. Gemini 2.5 Pro can take 10–30s on long visits; the very long developmental-eval template can push 60s. If you're past 2 minutes:
- Check Google Cloud status.
- Try switching to
gemini-2.5-flashin Settings as a temporary workaround — much faster, slightly lower quality. - Click Regenerate. The transcript is already stored locally; you're only paying for the LLM call.
Network drops / iOS Safari suspend
Common scenario: you start brtlb on an iPad, the upload is going, you switch to Elation in another tab to grab a patient name. iOS suspends the brtlb tab. The upload fails with "Load failed."
brtlb detects this and surfaces:
"The connection was interrupted. This usually means your Wi-Fi/cellular dropped, the brtlb tab was suspended (common on iOS when you switch apps mid-upload), or [vendor] is briefly unavailable. Reopen brtlb on a stable connection and tap Retry from audio."
What to do
- Switch back to the brtlb tab, click Reprocess from audio. brtlb has the audio blob in IndexedDB — no re-recording needed.
- To avoid this in the future: don't switch tabs while brtlb is uploading. On iPad, consider the in-app Stop → finish the visit → step away pattern.
Audio storage issues
"Browser storage is not available"
You see this in Settings or on save errors. Causes (iOS Safari is the usual culprit):
- Private Browsing. iOS Safari silently fails localStorage writes in private mode. Disable private browsing for the brtlb tab.
- "Block All Cookies" in Settings → Safari → Privacy. Switch to "Block third-party cookies" or off.
- PWA installed but data isolated. If you "Add to Home Screen" then later open the same URL in Safari, you get two separate storage containers. Pick one and stick with it.
- ITP wipe. iOS wipes localStorage after 7 days of no first-party interaction. Use brtlb at least weekly.
"Device storage is full"
Amber banner appears during recording. IndexedDB filled up. The in-memory recording continues but new audio chunks aren't being persisted to backup storage — a tab crash from here on would lose audio.
- Stop the current recording cleanly (Stop button). The full audio still saves from in-memory.
- Delete old recordings or shorten audio retention in Settings → Privacy & Security.
- Restart brtlb.
Lost audio mid-recording
You see: "Recording was interrupted — Xs of audio lost."
Means the iOS / Android OS suspended the brtlb tab mid-capture (screen locked, app switched, etc.) and MediaRecorder stopped. brtlb acquires navigator.wakeLock at recording start to keep the screen awake, but if iOS overrides that (low battery mode, hardware lock button), the suspend can still happen.
What to do
- brtlb saves whatever audio it captured before the interruption. Stop and review — sometimes partial audio is enough.
- Re-record going forward: keep the brtlb tab in the foreground, screen on, until you hit Stop.
- The seafoam pre-record advisory in ambient mode reminds you of this. Read it once and you'll know the failure pattern.
"The microphone became unavailable"
Mid-recording error. Causes:
- Bluetooth / USB mic disconnected (AirPods walked out of range, USB unplugged).
- Another app took the mic (incoming FaceTime call accepted, Zoom started).
- Mic permission revoked in browser settings.
Stop, re-grant permission if needed, and re-record when the mic is available. Brief mic mutes (incoming call ignored) are tolerated; permanent loss is what triggers this error.
API key errors
"401 Unauthorized" from AssemblyAI
Your key is wrong or revoked. Settings → AssemblyAI key. Re-paste from your AAI dashboard.
"Workspace org policy block" from Gemini
Your Google Cloud project doesn't permit the Gemini API call. Two common causes:
- The project doesn't have billing enabled. Add a billing account in Cloud Console.
- Your Workspace org policy restricts AI APIs. Talk to your admin or use a personal Cloud project for testing.
"Anthropic API blocked by CORS"
Anthropic Enterprise (BAA-covered) keys block browser CORS calls — there's no current path for browser-only Anthropic with PHI. Use Gemini or Azure OpenAI for PHI; Anthropic is fine for non-PHI testing.
Wrong template auto-picked
Auto-detection looks at the transcript and picks soap / well-child / sick-visit / etc. When it picks wrong:
- Change the dropdown above the note to your preferred template.
- Click Regenerate. No re-transcription, just a new LLM pass.
- If a specific template type keeps mis-routing, write a custom template that captures your conventions and pin it. Customize → templates.
Note is missing detail you discussed
Three common causes:
- STT garbled it. Open raw JSON, search for the topic. If AAI mis-transcribed a medication name or finding, the note can't pick up something it didn't see. Re-record with clearer audio or correct via Tweak with AI: "Patient is on Concerta 36mg, not Concerta 18."
- Discipline rules omitted it on purpose. brtlb defaults to omission over fabrication. If you said "patient is doing well" and the note doesn't include a separate "no concerns" section, that's working as designed. Add via Tweak with AI if you want it explicit.
- Token cap truncation. Check the coverage banner — if the last section ends mid-sentence, regenerate. If it keeps truncating, your template is too long.
Browser compatibility
brtlb checks four capabilities at boot. If any are missing, you get an explicit page telling you which:
- IndexedDB — for storing audio + transcripts locally. Disabled in private browsing on some browsers.
- MediaRecorder — for capturing audio. All modern browsers have this. Safari needs iOS 14.3+.
- navigator.mediaDevices.getUserMedia — for mic access. Requires HTTPS (brtlb.io is HTTPS; if you self-host on
http://localhost, that's special-cased OK). - crypto.subtle — for hashing. Effectively universal.
Tested baseline: Chrome 120+, Safari 17+ (iOS 17+), Firefox 121+, Edge 120+. Older browsers may render but features will be flaky.
Nuclear option — reset
If brtlb is acting weird and nothing else helps, the global error boundary's recovery screen has a "Wipe local data and reload" button. This:
- Clears IndexedDB (all recordings, audio, transcripts gone).
- Clears localStorage (settings, API keys, theme, etc.).
- Reloads to a fresh first-run state.
To trigger the recovery screen manually: open the browser console and run localStorage.setItem('brtlb.crash-test', '1') — that exposes the same recovery UI without losing data.