Agent skill

Riverpod Stream Provider Auth Transition Oscillation

by divinevideo in divinevideo/divine-mobile

Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes.

MPL-2.0Auto-check passedMobile

Install Riverpod Stream Provider Auth Transition Oscillation

skills CLI
$ npx skills add divinevideo/divine-mobile --skill riverpod-stream-provider-auth-transition-oscillation -a claude-code

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

GitHub CLI
$ gh skill install divinevideo/divine-mobile riverpod-stream-provider-auth-transition-oscillation --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-stream-provider-auth-transition-oscillation .claude/skills/riverpod-stream-provider-auth-transition-oscillation && 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-stream-provider-auth-transition-oscillation
GitHub stars
266
Token cost
~2k tokens
SKILL.md length
567 words
Files
1
Skills in repo
103
Repo updated
First seen
Licence
MPL-2.0

At a glance

Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes.

  • Works in 3 steps: Read URL index synchronously from GoRouter → Watch the data provider directly → Remove unused intermediate provider…
  • Screen shows BrandedLoadingIndicator
  • SKILL.md covers Problem, Context / Trigger Conditions, Root Cause Analysis and Solution, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Riverpod Stream Provider Auth Transition Oscillation is an agent skill from divinevideo/divine-mobile. Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes. Use when: (1) Screen shows BrandedLoadingIndicator or CircularProgressIndicator permanently after successful auth redirect, (2) Widget watches a route-type-gating provider that returns AsyncValue.loading() intermittently, (3) Logs show route location oscillating between stale and current paths during post-login transition (e.g., /welcome/ after /home/0), (4) Provider…

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

It sits in Mobile, covering Cross-platform mobile apps. It works with Flutter. The licence is MPL-2.0.

When your agent uses it

  • Screen shows BrandedLoadingIndicator
  • CircularProgressIndicator permanently after successful auth redirect
  • Widget watches a route-type-gating provider that returns AsyncValue.loading() intermittently
  • Logs show route location oscillating between stale and current paths during post-login transition (e.g.

Example prompts

  • “/riverpod-stream-provider-auth-transition-oscillation”

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. Read URL index synchronously from GoRouter
  2. Watch the data provider directly
  3. Remove unused intermediate provider imports

What it can do on your machine

Read from SKILL.md and the folder at commit c3d6f7e. 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

    No URLs in SKILL.md.

    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 Stream Provider Auth Transition Oscillation loads about 2k tokens when it runs. Until then it costs about 198 tokens; SKILL.md has 567 words of instructions outside code blocks.

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

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 c3d6f7e, republished under its MPL-2.0 licence (© divinevideo). 567 words, ~1,956 tokens.

Download SKILL.mdSave it as .claude/skills/riverpod-stream-provider-auth-transition-oscillation/SKILL.md (or your agent's skills folder).
name
riverpod-stream-provider-auth-transition-oscillation
description
Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes. Use when: (1) Screen shows BrandedLoadingIndicator or CircularProgressIndicator permanently after successful auth redirect, (2) Widget watches a route-type-gating provider that returns AsyncValue.loading() intermittently, (3) Logs show route location oscillating between stale and current paths during post-login transition (e.g., /welcome/* after /home/0), (4) Provider chain has double-gate: widget gates on pageContext AND data provider also gates on pageContext. Distinct from riverpod-infinite-rebuild-loop (rapid rebuilds) — this causes permanent loading state, not infinite rebuilds.
author
Claude Code
version
1.0.0
date
2026-02-16

Riverpod StreamProvider Auth Transition Oscillation

Problem

After successful login and redirect, the main screen (home feed, dashboard, etc.) is permanently stuck on a loading indicator. The auth redirect works correctly (URL shows /home/0), but the screen never renders data. This is NOT a rapid rebuild issue — the widget builds a few times then settles on a loading state.

Context / Trigger Conditions

Symptoms:

  • Screen stuck on loading spinner after successful login redirect
  • URL bar / GoRouter shows correct path (e.g., /home/0)
  • Data provider (e.g., homeFeedProvider) has data if checked directly
  • No error messages — just permanent loading
  • May show brief flash of content before reverting to loading

Architecture that triggers this:

  1. A StreamProvider that watches router.routerDelegate for location changes
  2. This stream parses routes into a RouteContext with a type field (home, explore, etc.)
  3. Downstream providers gate on routeContext.type == RouteType.home and return AsyncValue.loading() when the type doesn't match
  4. The widget watches the downstream provider and shows loading indicator

The oscillation pattern:

Auth state changes → Router redirects to /home/0
  → routerDelegate emits /home/0 ✓
  → routerDelegate emits /welcome/login (stale!) ✗
  → routerDelegate emits /home/0 ✓
  → routerDelegate emits /welcome/* (stale!) ✗
  ...oscillates for several frames

Why it happens: GoRouter's routerDelegate listener fires for EVERY location change during transitions, including intermediate/stale states. During post-login, the router processes multiple pending navigations (pop welcome screen, push home screen) and the delegate emits each intermediate state. A sync StreamController propagates these instantly.

Log signature:

CTX derive: type=RouteType.home npub=null index=0
CTX derive: type=RouteType.welcome npub=null index=null   ← stale!
CTX derive: type=RouteType.home npub=null index=0

Root Cause Analysis

The issue is a double gate on an oscillating stream:

routerDelegate listener
  ↓ (emits every location change)
StreamProvider<RouteContext>  ← oscillates between /home and /welcome
  ↓
videosForHomeRouteProvider   ← returns loading() when type != home  [GATE 1]
  ↓
HomeScreenRouter.build()     ← watches pageContext for type check   [GATE 2]

When the stream oscillates, both gates open and close rapidly. The widget ends up rendering the loading state from whichever emission came last in the settling period.

Solution

Pattern: "I Know Who I Am" — Bypass Route-Type Gating

When a widget knows its own context (it's only mounted at a specific route), it doesn't need to gate on a route-type stream. It can read route info synchronously.

Step 1: Read URL index synchronously from GoRouter
dart
// BEFORE: Watching oscillating stream
final pageContext = ref.watch(pageContextProvider);
return pageContext.when(
  data: (ctx) {
    if (ctx.type != RouteType.home) return loading();
    // ...
  },
  loading: () => loading(),
  error: (e, s) => error(),
);

// AFTER: Read synchronously — this widget IS the home screen
final router = ref.read(goRouterProvider);
final location = router.routeInformationProvider.value.uri.toString();
final segments = location.split('/').where((s) => s.isNotEmpty).toList();
int urlIndex = 0;
if (segments.length > 1 && segments[0] == 'home') {
  urlIndex = int.tryParse(segments[1]) ?? 0;
}
Step 2: Watch the data provider directly
dart
// BEFORE: Watching intermediate provider that gates on route type
final videosAsync = ref.watch(videosForHomeRouteProvider);

// AFTER: Watch the data provider directly — no route-type gate needed
final videosAsync = ref.watch(homeFeedProvider);
Step 3: Remove unused intermediate provider imports

Clean up imports for any intermediate route-gating providers that are no longer used.

Show full SKILL.md (247 more words)Show less

When NOT to Apply This Fix

  • When the widget genuinely needs to render different content based on route type (e.g., a shared shell that shows different feeds)
  • When the widget is mounted at multiple routes and needs to switch behavior
  • If the issue is actually rapid rebuilds (use riverpod-infinite-rebuild-loop instead)

Verification

After the fix:

  1. Login → redirect to home → home feed loads immediately (no permanent spinner)
  2. No RAPID REBUILD warnings (this fix doesn't cause those)
  3. Swipe through feed works normally
  4. Pull-to-refresh works
  5. Navigate away and back — feed still loads
  6. Test with ref.watch(homeFeedProvider) in initState to confirm data arrives

Example: Complete Fix (HomeScreenRouter)

Before (stuck on loading):

dart
@override
Widget build(BuildContext context) {
  final pageContext = ref.watch(pageContextProvider);
  return buildAsyncUI(
    pageContext,
    onData: (ctx) {
      if (ctx.type != RouteType.home) {
        return const Center(child: BrandedLoadingIndicator(size: 80));
      }
      final videosAsync = ref.watch(videosForHomeRouteProvider);
      return buildAsyncUI(videosAsync, ...);
    },
  );
}

After (loads correctly):

dart
@override
Widget build(BuildContext context) {
  // Read URL synchronously — HomeScreenRouter is only at /home/:index
  final router = ref.read(goRouterProvider);
  final location = router.routeInformationProvider.value.uri.toString();
  final segments = location.split('/').where((s) => s.isNotEmpty).toList();
  int urlIndex = 0;
  if (segments.length > 1 && segments[0] == 'home') {
    urlIndex = int.tryParse(segments[1]) ?? 0;
  }

  // Watch data directly — no route-type gate needed
  final videosAsync = ref.watch(homeFeedProvider);
  return buildAsyncUI(videosAsync, onData: (state) { ... });
}

Notes

  • Distinct from rebuild loops: riverpod-infinite-rebuild-loop covers rapid rebuilds (50+ per second). This issue causes 3-8 rebuilds that settle on a LOADING state.
  • Related to auth timing: Often co-occurs with synchronous router redirect needing data that isn't yet available. See companion fix: pre-fetch data before setting auth state so redirects have what they need.
  • StreamProvider vs read: The oscillation only affects StreamProvider watching reactive router state. ref.read() of GoRouter's current location is stable.
  • GoRouter's routerDelegate: This listener fires for every intermediate navigation state. It's reliable for final states but oscillates during multi-step transitions (login → pop welcome → push home).
  • Debug technique: Add print('CTX derive: type=${ctx.type}') to the StreamProvider to see the oscillation pattern.
  • riverpod-infinite-rebuild-loop — rapid rebuilds from watch/listener issues
  • flutter-pageview-url-routing-reorder-loop — infinite loop from item reorder tracking
  • flutter-startup-network-blocking — blocking network ops during startup

© 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-stream-provider-auth-transition-oscillation of divinevideo/divine-mobile.

Open the folder on GitHubat commit c3d6f7e

Compare with similar skills

Riverpod Stream Provider Auth Transition Oscillation 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 Stream Provider Auth Transition Oscillation compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Riverpod Stream Provider Auth Transition Oscillation this skilldivinevideo/divine-mobile266—~2kAutomated safety check: PassMPL-2.0
Add Flutter Docusaurus Localematthiasn/lotti1.2k—~1.2kAutomated safety check: PassGPL-3.0
Tm Launcher DesignFar-Se/tabame372—~3.1kAutomated safety check: PassMIT
Flutter Initbear2u/my-skills932—~2.5kAutomated safety check: PassNone
Mobile App UI Designceorkm/mobile-app-ui-design409—~2kAutomated safety check: PassNone
Marionette Flutter Drive Appleancodepl/marionette_mcp482—~11kAutomated safety check: PassApache-2.0

Similar skills

  • Add, complete, or audit a locale across a Flutter application's ARB catalogs and a localized Docusaurus manual, including generated localization code, locale selectors, native platform declarations…

    1.2k GitHub stars~1.2k tokensUpdated today
    MobileAuto-check passed
  • Tm Launcher Design

    Far-Se/tabame

    Create or revise Tabame's Flutter launcher designs: frames, search bars, result rows, palettes, typography, and action dialogs.

    372 GitHub stars~3.1k tokensUpdated yesterday
    MobileAuto-check passed
  • Flutter Init

    bear2u/my-skills

    A skill your agent uses when user wants to create a new Flutter project (Todo/Habit/Note/Expense/Custom domain) with Clean Architecture, Riverpod 3.0, Drift, and modern Flutter stack

    932 GitHub stars~2.5k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Mobile App UI Design

    ceorkm/mobile-app-ui-design

    Design high-quality mobile app UI/UX screens, flows, and components.

    409 GitHub stars~2k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Marionette Flutter Drive App

    leancodepl/marionette_mcp

    Set up and drive a running Flutter app (debug or profile) with Marionette — an AI agent's hands and eyes for the app.

    482 GitHub stars~11k tokensUpdated 5 days ago
    MobileAuto-check passed
  • Flutter Screenshot

    JustLookAtNow/pt_mate

    Capture and show two Flutter UI screenshots for this project: one landscape/large-screen preview and one portrait/mobile preview, without using Flutter Web.

    504 GitHub stars~511 tokensUpdated yesterday
    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

Works with

Categories

Questions about Riverpod Stream Provider Auth Transition Oscillation

What does Riverpod Stream Provider Auth Transition Oscillation do?

Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes. Riverpod Stream Provider Auth Transition Oscillation is an agent skill from divinevideo/divine-mobile. Fix Flutter home feed / main screen stuck on loading spinner after login when using Riverpod StreamProvider that watches GoRouter location changes.

When should I use Riverpod Stream Provider Auth Transition Oscillation?

Riverpod Stream Provider Auth Transition Oscillation fits situations like: screen shows BrandedLoadingIndicator; circularProgressIndicator permanently after successful auth redirect; widget watches a route-type-gating provider that returns AsyncValue.loading() intermittently; logs show route location oscillating between stale and current paths during post-login transition (e.g.

How do I install Riverpod Stream Provider Auth Transition Oscillation in Claude Code?

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

How do I install Riverpod Stream Provider Auth Transition Oscillation in Codex?

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

Can I use Riverpod Stream Provider Auth Transition Oscillation 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-stream-provider-auth-transition-oscillation -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-stream-provider-auth-transition-oscillation, .gemini/skills/riverpod-stream-provider-auth-transition-oscillation, .github/skills/riverpod-stream-provider-auth-transition-oscillation and .opencode/skills/riverpod-stream-provider-auth-transition-oscillation in your project.

What does Riverpod Stream Provider Auth Transition Oscillation need to run?

SKILL.md names no scripts, command-line tools or credentials: Riverpod Stream Provider Auth Transition Oscillation is instructions for the agent only.

Does Riverpod Stream Provider Auth Transition Oscillation access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Riverpod Stream Provider Auth Transition Oscillation 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 Stream Provider Auth Transition Oscillation use?

Riverpod Stream Provider Auth Transition Oscillation 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 Stream Provider Auth Transition Oscillation use?

About 2k tokens (SKILL.md is roughly 7.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 Stream Provider Auth Transition Oscillation?

Skills that share tags, products or a category with Riverpod Stream Provider Auth Transition Oscillation: Add Flutter Docusaurus Locale (matthiasn/lotti, 1.2k stars), Tm Launcher Design (Far-Se/tabame, 372 stars), Flutter Init (bear2u/my-skills, 932 stars) and Mobile App UI Design (ceorkm/mobile-app-ui-design, 409 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Riverpod Stream Provider Auth Transition Oscillation?

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 10, 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.