Skip to content

fix conversation detail download audio Navigator null crash#7589

Open
krushnarout wants to merge 3 commits into
mainfrom
fix/conversation-detail-navigator-null-context
Open

fix conversation detail download audio Navigator null crash#7589
krushnarout wants to merge 3 commits into
mainfrom
fix/conversation-detail-navigator-null-context

Conversation

@krushnarout
Copy link
Copy Markdown
Member

Crash

_ConversationDetailPageState._downloadAudio

Error: FlutterError - Null check operator used on a null value
package:omi/pages/conversation_detail/page.dart:584

Crashlytics: https://console.firebase.google.com/u/0/project/based-hardware/crashlytics/app/ios:com.friend-app-with-wearable.ios12/issues/9847dad06f42b3d650cb74fa0a169732?time=7d&types=crash&sessionEventKey=2b3db86de2c341d5814d995b3ce760c9_2223656953270793706

Logs:

Fatal Exception: FlutterError
0  ???  0x0 StatefulElement.state + 5840 (framework.dart:5840)
1  ???  0x0 Navigator.of + 2900 (navigator.dart:2900)
2  ???  0x0 _ConversationDetailPageState._downloadAudio + 584 (page.dart:584)
3  ???  0x0 _ConversationDetailPageState._handleMenuSelection + 341 (page.dart:341)

Fix

Primary crash: Navigator.of(sheetContext) internally force-unwraps the navigator ancestor. If the page is popped during the long audio download (network + processing), the context is no longer in the tree and the unwrap crashes. Fixed by replacing all three Navigator.of(sheetContext).pop() calls with Navigator.maybeOf(sheetContext)?.pop(), which safely no-ops when the navigator is gone.

Context guard fixes found alongside:

  • if (mounted) was guarding sheetContext-based Navigator pops — should be sheetContext.mounted since mounted (State) and the sheet's context are unrelated
  • ScaffoldMessenger.of(context) in the catch block was guarded by State mounted — changed to context.mounted since context is the parameter BuildContext, not this.context
  • Star toggle button: if (!mounted) return guarded context.read<>() and ScaffoldMessenger.of(context) — changed to context.mounted for the same reason
  • showReviewPromptIfNeeded(context, ...) after two awaits in action item toggle had no mounted guard — added if (mounted) before the call

🤖 Generated with Claude Code

krushnarout and others added 3 commits June 2, 2026 14:39
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s.dart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 2, 2026

Greptile Summary

This PR fixes a Null check operator used on a null value crash in _downloadAudio when the conversation detail page is popped while a long audio download is in progress, plus several related async-after-dismount context guard bugs found alongside it.

  • Primary crash fix: All three Navigator.of(sheetContext).pop() calls are replaced with Navigator.maybeOf(sheetContext)?.pop(), guarded by sheetContext.mounted instead of the State's mounted. This prevents the force-unwrap crash when the page is dismissed mid-download.
  • Context guard corrections: The mounted (State property) guards in the star-toggle callback and ScaffoldMessenger catch block are updated to context.mounted, and a missing if (mounted) guard is added before showReviewPromptIfNeeded in _ActionItemDetailWidgetState after two awaits.

Confidence Score: 4/5

Safe to merge — all changes are targeted async-safety guards that eliminate a confirmed production crash and correct nearby context-lifetime mismatches without altering any business logic.

All five changes directly address real widget-lifetime bugs that were either causing confirmed crashes or silently using stale contexts after async gaps. The fixes are minimal and localized, and the underlying download/star-toggle logic is unchanged.

No files require special attention — the single changed file has well-scoped, straightforward guard corrections.

Important Files Changed

Filename Overview
app/lib/pages/conversation_detail/page.dart Five targeted async-safety fixes: Navigator crash addressed with maybeOf, three mounted-guard context mismatches corrected, and a missing guard added before showReviewPromptIfNeeded. One minor residual: updateSheet?.call() invocations inside the download callbacks have no mounted check for the sheet's StatefulBuilder setState, but this is pre-existing and out of scope.

Sequence Diagram

sequenceDiagram
    participant User
    participant DetailPage as ConversationDetailPage
    participant Sheet as AudioDownloadProgressSheet
    participant Service as AudioDownloadService

    User->>DetailPage: tap "Download Audio"
    DetailPage->>Sheet: showModalBottomSheet(isDismissible:false)
    DetailPage->>Service: downloadAndCombineAudio()

    Note over User,Service: Long async operation (network + processing)

    alt User navigates away mid-download
        User->>DetailPage: pop page
        DetailPage-->>Sheet: (sheet also dismissed by Flutter)
    end

    alt Download succeeds
        Service-->>DetailPage: returns File
        DetailPage->>DetailPage: sheetContext.mounted?
        DetailPage->>Sheet: Navigator.maybeOf(sheetContext)?.pop()
        DetailPage->>User: Share.shareXFiles(...)
    else No audio available
        Service-->>DetailPage: returns null
        DetailPage->>DetailPage: sheetContext.mounted?
        DetailPage->>Sheet: Navigator.maybeOf(sheetContext)?.pop()
    else Error during download
        Service-->>DetailPage: throws exception
        DetailPage->>DetailPage: sheetContext.mounted?
        DetailPage->>Sheet: Navigator.maybeOf(sheetContext)?.pop()
        DetailPage->>DetailPage: context.mounted?
        DetailPage->>User: ScaffoldMessenger.showSnackBar(error)
    end

    DetailPage->>DetailPage: "finally: if(mounted) setState(_isDownloadingAudio=false)"
Loading

Reviews (1): Last reviewed commit: "Revert "chore remove unused _copyContent..." | Re-trigger Greptile

Copy link
Copy Markdown
Collaborator

@kodjima33 kodjima33 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug fix: replaces unsafe Navigator.of(sheetContext) with Navigator.maybeOf(sheetContext)?.pop() in conversation detail audio download path, plus correct context.mounted guards in adjacent callbacks. Small (21 lines), single file, addresses a real Crashlytics issue.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants