Agent skill

Riverpod Ref In Provider Lifecycle

by divinevideo in divinevideo/divine-mobile

Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies.

MPL-2.0Auto-check passed

Install Riverpod Ref In Provider Lifecycle

skills CLI
$ npx skills add divinevideo/divine-mobile --skill riverpod-ref-in-provider-lifecycle -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install divinevideo/divine-mobile riverpod-ref-in-provider-lifecycle --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/divinevideo/divine-mobile.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/riverpod-ref-in-provider-lifecycle .claude/skills/riverpod-ref-in-provider-lifecycle && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
riverpod-ref-in-provider-lifecycle
GitHub stars
266
Token cost
~1.5k tokens
SKILL.md length
313 words
Files
1
Skills in repo
103
Repo updated
First seen
Licence
MPL-2.0

At a glance

Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies.

  • Works in 4 steps: Provider uses ref.keepAlive() with a… → Provider has async callbacks that use ref → Timer fires while async callback is… → …
  • Crash during provider disposal with this exact error message
  • SKILL.md covers Problem, Context / Trigger Conditions, Solution and Anti-Pattern: ref.mounted Check, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Riverpod Ref In Provider Lifecycle is an agent skill from divinevideo/divine-mobile. Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies. Use when: (1) Crash during provider disposal with this exact error message, (2) Using keepAlive() with timer-based disposal, (3) Async callbacks (.then, .catchError) try to use ref.read() or ref.invalidateSelf(), (4) Error occurs after ref.onCancel/onResume/onDispose callbacks fire. Solution: wrap ref operations in try-catch or avoid using ref in async callbacks entirely.

Its SKILL.md is about 1.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The licence is MPL-2.0.

When your agent uses it

  • Crash during provider disposal with this exact error message
  • Using keepAlive() with timer-based disposal
  • Async callbacks (.then
  • .catchError) try to use ref.read()

Example prompts

  • “Cannot use Ref or modify other providers inside life-cycles/selectors”
  • “/riverpod-ref-in-provider-lifecycle”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Provider uses ref.keepAlive() with a timer in ref.onCancel()
  2. Provider has async callbacks that use ref
  3. Timer fires while async callback is pending
  4. CRASH - ref.mounted returns true but using ref is still forbidden

What it can do on your machine

Read from SKILL.md and the folder at commit 6487b05. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are dart).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • riverpod.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Riverpod Ref In Provider Lifecycle loads about 1.5k tokens when it runs. Until then it costs about 133 tokens; SKILL.md has 313 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~133
When it runs · the whole SKILL.md, loaded when a task matches
~1.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from divinevideo/divine-mobile at commit 6487b05, republished under its MPL-2.0 licence (© divinevideo). 313 words, ~1,454 tokens.

Download SKILL.mdSave it as .claude/skills/riverpod-ref-in-provider-lifecycle/SKILL.md (or your agent's skills folder).
name
riverpod-ref-in-provider-lifecycle
description
Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies. Use when: (1) Crash during provider disposal with this exact error message, (2) Using keepAlive() with timer-based disposal, (3) Async callbacks (.then, .catchError) try to use ref.read() or ref.invalidateSelf(), (4) Error occurs after ref.onCancel/onResume/onDispose callbacks fire. Solution: wrap ref operations in try-catch or avoid using ref in async callbacks entirely.
author
Claude Code
version
1.0.0
date
2026-02-01

Riverpod ref Usage in Provider Lifecycle Callbacks

Problem

When using ref.keepAlive() with timer-based auto-disposal in @riverpod providers, async callbacks (.then(), .catchError()) that execute during or after disposal will crash when they try to use ref.read(), ref.invalidateSelf(), or any other ref operation.

Context / Trigger Conditions

Error message:

'package:riverpod/src/core/ref.dart': Failed assertion: line 216 pos 7:
'_debugCallbackStack == 0': Cannot use Ref or modify other providers inside life-cycles/selectors.

Typical scenario:

  1. Provider uses ref.keepAlive() with a timer in ref.onCancel():
dart
final link = ref.keepAlive();
ref.onCancel(() {
  Timer(Duration(seconds: 15), () {
    link.close();  // Triggers disposal
  });
});
  1. Provider has async callbacks that use ref:
dart
someAsyncOperation().then((_) {
  if (ref.mounted) {  // THIS CHECK IS NOT ENOUGH!
    ref.invalidateSelf();
  }
});
  1. Timer fires while async callback is pending
  2. CRASH - ref.mounted returns true but using ref is still forbidden

Key insight: ref.mounted returns true during lifecycle callbacks, but using ref operations is still forbidden. This is counter-intuitive but by design.

Solution

dart
someAsyncOperation().then((_) {
  try {
    ref.read(someProvider.notifier).update(/*...*/);
  } catch (e) {
    Log.debug('Provider likely disposed: $e');
  }
});
Option 2: Avoid ref operations in async callbacks entirely

Instead of:

dart
// BAD - uses ref in async callback
openVineVideoCache.removeCorruptedVideo(videoId).then((_) {
  if (ref.mounted) {
    ref.invalidateSelf();  // CRASH!
  }
});

Do:

dart
// GOOD - fire-and-forget without ref
unawaited(
  openVineVideoCache.removeCorruptedVideo(videoId).then((_) {
    Log.info('Cache removed');  // No ref usage
  }),
);
// Let user retry manually or provider recreates on next access
Option 3: Capture provider state synchronously first
dart
// Read state BEFORE async operation
final notifier = ref.read(someProvider.notifier);

// Use captured reference in callback (not ref)
someAsyncOperation().then((_) {
  notifier.doSomething();  // Uses captured reference, not ref
});

Anti-Pattern: ref.mounted Check

dart
// THIS DOES NOT WORK!
someAsyncOperation().then((_) {
  if (ref.mounted) {  // Returns true during lifecycle!
    ref.invalidateSelf();  // Still crashes!
  }
});

The ref.mounted check is insufficient because:

  1. Timer fires, link.close() called
  2. Riverpod enters disposal lifecycle (callback stack > 0)
  3. ref.mounted check passes (still returns true!)
  4. ref.invalidateSelf() called
  5. CRASH - ref operations forbidden during lifecycle callbacks

Verification

  1. Rapidly scroll through content that uses the provider
  2. Navigate away and back while providers are active
  3. Let the keepAlive timers fire naturally (wait 15+ seconds after scrolling)
  4. Check Crashlytics/console for the lifecycle assertion error
  5. Error should no longer occur

Example

Before (causes crash):
dart
@riverpod
VideoPlayerController videoController(Ref ref, String videoId) {
  final link = ref.keepAlive();

  ref.onCancel(() {
    Timer(Duration(seconds: 15), () => link.close());
  });

  final controller = VideoPlayerController.networkUrl(url);

  controller.initialize().catchError((error) {
    // CRASH! This callback may run during disposal
    if (ref.mounted) {
      ref.invalidateSelf();  // Assertion failure!
    }
  });

  return controller;
}
After (safe):
dart
@riverpod
VideoPlayerController videoController(Ref ref, String videoId) {
  final link = ref.keepAlive();

  ref.onCancel(() {
    Timer(Duration(seconds: 15), () => link.close());
  });

  final controller = VideoPlayerController.networkUrl(url);

  controller.initialize().catchError((error) {
    // Safe - wrapped in try-catch
    try {
      ref.read(fallbackProvider.notifier).state = newValue;
    } catch (e) {
      Log.debug('Provider disposed during error handling: $e');
    }
    // Don't invalidateSelf - let provider recreate on next access
  });

  return controller;
}

Notes

  • This issue is specific to @riverpod provider bodies, not widget dispose()
  • The related skill riverpod-ref-read-in-dispose covers widget lifecycle issues
  • Consider whether ref.invalidateSelf() is even necessary - often the provider will be recreated naturally on next access
  • For truly critical cleanup, use ref.onDispose() which runs synchronously before the lifecycle callback stack check
  • This bug is particularly common with video players, image loaders, and other resources that use keepAlive() with timer-based disposal
  • riverpod-ref-read-in-dispose: For widget dispose() ref.read() issues
  • flutter-dispose-timer-test-failure: For timer-related test failures

References

© divinevideo, MPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/riverpod-ref-in-provider-lifecycle of divinevideo/divine-mobile.

Open the folder on GitHubat commit 6487b05

Compare with similar skills

Riverpod Ref In Provider Lifecycle next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Riverpod Ref In Provider Lifecycle compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Riverpod Ref In Provider Lifecycle this skilldivinevideo/divine-mobile266—~1.5kAutomated safety check: PassMPL-2.0
Flutter Riverpod State Managementandrewyng/context-hub14k—~1.1kAutomated safety check: PassMIT
React18 String Refsgithub/awesome-copilot40k1 repos~527Automated safety check: PassMIT
Add Model Provideropenclaw/openclaw392k—~1.1kAutomated safety check: PassMIT
OmniRoute Provider Managementdiegosouzapw/OmniRoute74k—~2.4kAutomated safety check: PassMIT
OmniRoute Providers CLIdiegosouzapw/OmniRoute74k—~2.2kAutomated safety check: PassMIT

Similar skills

  • Guides Flutter state management with Riverpod: choosing provider types, wiring ConsumerWidgets, handling async state and lifecycle, and overriding providers in tests.

    14k GitHub stars~1.1k tokensUpdated 4 mo ago
    MobileAuto-check passed
  • React18 String Refs

    github/awesome-copilot

    Official

    Provides exact migration patterns for React string refs (ref="name" + this.refs.name) to React.createRef() in class components.

    40k GitHub starsUsed in 1 repo~527 tokens
    Auto-check passed
  • Add Model Provider

    openclaw/openclaw

    Add and live-prove a model provider with non-interactive config one-liners, without exposing credentials.

    392k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • OmniRoute Provider Management

    diegosouzapw/OmniRoute

    Manages AI provider connections, API keys, OAuth flows and connection tests through OmniRoute's REST API across its 327-provider catalog.

    74k GitHub stars~2.4k tokensUpdated today
    Backend & APIsAuto-check passed
  • OmniRoute Providers CLI

    diegosouzapw/OmniRoute

    Command reference for managing provider connections in the omniroute gateway: browse the catalog, test and validate connections, rotate API keys and read per-provider metrics.

    74k GitHub stars~2.2k tokensUpdated today
    AI & LLM EngineeringAuto-check passed
  • Riverpod

    evanca/flutter-ai-rules

    A skill your agent uses when setting up providers, combining requests, managing state disposal, passing arguments, performing side effects, or testing providers (Riverpod).

    650 GitHub stars~1.8k tokensUpdated 25 days ago
    MobileAuto-check passed

More from divinevideo/divine-mobile

All 103 skills in this repo
  • Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y".

    266 GitHub stars~931 tokensUpdated today
    Auto-check passed
  • Art Direct

    divinevideo/divine-mobile

    Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language.

    266 GitHub stars~4.8k tokensUpdated today
    Auto-check passed
  • Async Await Null Race Condition

    divinevideo/divine-mobile

    Fix "Null check operator used on a null value" errors when an object is set to null during an async await.

    266 GitHub stars~881 tokensUpdated today
    Auto-check passed
  • AWS V4 Signing Custom Headers Gcs

    divinevideo/divine-mobile

    Add custom metadata headers (x-amz-meta-) to AWS v4 signed requests for GCS S3-compatible API.

    266 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • Bash Herestring Newline Secrets

    divinevideo/divine-mobile

    Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings.

    266 GitHub stars~791 tokensUpdated today
    Auto-check passed
  • Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp).

    266 GitHub stars~1.1k tokensUpdated today
    Auto-check passed

Questions about Riverpod Ref In Provider Lifecycle

What does Riverpod Ref In Provider Lifecycle do?

Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies. Riverpod Ref In Provider Lifecycle is an agent skill from divinevideo/divine-mobile. Fix Riverpod "Cannot use Ref or modify other providers inside life-cycles/selectors" crash in @riverpod provider bodies.

When should I use Riverpod Ref In Provider Lifecycle?

Riverpod Ref In Provider Lifecycle fits situations like: crash during provider disposal with this exact error message; using keepAlive() with timer-based disposal; async callbacks (.then; .catchError) try to use ref.read().

How do I install Riverpod Ref In Provider Lifecycle in Claude Code?

Run `npx skills add divinevideo/divine-mobile --skill riverpod-ref-in-provider-lifecycle -a claude-code`. Or copy the skill folder (.agents/skills/riverpod-ref-in-provider-lifecycle in divinevideo/divine-mobile) into .claude/skills/riverpod-ref-in-provider-lifecycle in your project. Claude Code loads it when a task matches its description.

How do I install Riverpod Ref In Provider Lifecycle in Codex?

Run `npx skills add divinevideo/divine-mobile --skill riverpod-ref-in-provider-lifecycle -a codex`. Or copy the skill folder (.agents/skills/riverpod-ref-in-provider-lifecycle in divinevideo/divine-mobile) into .agents/skills/riverpod-ref-in-provider-lifecycle in your project. Codex loads it when a task matches its description.

Can I use Riverpod Ref In Provider Lifecycle in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add divinevideo/divine-mobile --skill riverpod-ref-in-provider-lifecycle -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/riverpod-ref-in-provider-lifecycle, .gemini/skills/riverpod-ref-in-provider-lifecycle, .github/skills/riverpod-ref-in-provider-lifecycle and .opencode/skills/riverpod-ref-in-provider-lifecycle in your project.

What does Riverpod Ref In Provider Lifecycle need to run?

SKILL.md names no scripts, command-line tools or credentials: Riverpod Ref In Provider Lifecycle is instructions for the agent only.

Does Riverpod Ref In Provider Lifecycle access the network?

SKILL.md names 1 domain. As links in the text: riverpod.dev. This is read from the text; nothing was executed.

Is Riverpod Ref In Provider Lifecycle safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Riverpod Ref In Provider Lifecycle use?

Riverpod Ref In Provider Lifecycle is published under the MPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Riverpod Ref In Provider Lifecycle use?

About 1.5k tokens (SKILL.md is roughly 5.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Riverpod Ref In Provider Lifecycle?

Skills that share tags, products or a category with Riverpod Ref In Provider Lifecycle: Flutter Riverpod State Management (andrewyng/context-hub, 14k stars), React18 String Refs (github/awesome-copilot, 40k stars), Add Model Provider (openclaw/openclaw, 392k stars) and OmniRoute Provider Management (diegosouzapw/OmniRoute, 74k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Riverpod Ref In Provider Lifecycle?

divinevideo (a GitHub organization) maintains it in divinevideo/divine-mobile, which has 266 GitHub stars. The repository holds 103 skills in this directory. The repository was last updated on October 9, 2026.

Source: divinevideo/divine-mobile on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.