Skip to content

Null check error on register when state disposed #659

Description

@lpaletta-1

Describe the bug

TypeError: Null check operator used on a null value thrown from inside the showcaseview package (5.1.0), not from our app code.

The crash happens in a post-frame callback that the package schedules in the ShowcaseController.register constructor (showcase_controller.dart:62):

WidgetsBinding.instance.addPostFrameCallback((_) => _initRootWidget());

_initRootWidget() (showcase_controller.dart:277) accesses _context, which is getState().context (showcase_controller.dart:120). When it reaches
State.context (framework.dart:959), the framework performs a null-check on the State's _element. If the Showcase has already been unmounted from the tree
(State no longer mounted) between the moment the callback was scheduled and the next frame being drawn, _element is null and the ! operator throws.

In short: it's a race condition between the showcase registration and the widget being disposed. _initRootWidget does not check mounted before touching
the context (unlike other methods of the same controller such as setupShowcase, which does validate _mounted).

To Reproduce
Steps to reproduce the behavior:

  1. Navigate to a screen that contains a Showcase (a widget with a tutorial/onboarding).
  2. Cause that screen to be unmounted immediately (route pop, tab switch, or a rebuild that removes the Showcase) within the same frame it is mounted.
  3. Wait for the next frame: this fires the post-frame callback _initRootWidget on an already-unmounted State.
  4. See the error (Null check operator used on a null value).

▎ Note: it's intermittent / timing-dependent, which is why it shows up as a production crash and not consistently.

Expected behavior

The showcase should not crash when the widget is unmounted before the post-frame callback runs. _initRootWidget (and register) should validate
getState().mounted before accessing context, or the callback should abort silently if the showcase is no longer in the tree.

Screenshots
N/A — runtime crash reported via Sentry.

Desktop (please complete the following information):

  • OS: N/A

Smartphone (please complete the following information):

  • Device: Android (reported from base.apk)
  • OS: Android
  • App: app-waiters
  • Package: showcaseview: 5.1.0

Additional context

Stacktrace:

TypeError: Null check operator used on a null value
State.context (framework.dart:959)
ShowcaseController._context (showcase_controller.dart:120)
ShowcaseController._initRootWidget (showcase_controller.dart:277)
ShowcaseController.register. (showcase_controller.dart:62)
SchedulerBinding._invokeFrameCallback (binding.dart:1430)
SchedulerBinding.handleDrawFrame (binding.dart:1357)
SentryWidgetsBindingMixin.handleDrawFrame (binding_wrapper.dart:128)
...

  • Captured via Sentry (SentryWidgetsBindingMixin).
  • Surfaces when upgrading to / using showcaseview 5.1.0.
  • Root cause: _initRootWidget accesses State.context in a post-frame callback without checking mounted. Possible app-level workaround: ensure Showcase
    widgets are not unmounted in the same frame they're mounted; proper fix: report/patch upstream so that register/_initRootWidget check mounted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions