immich-app/immich · error · Exception

User must be logged in to access this provider

Error message

User must be logged in to access this provider

What it means

authUserProvider is a non-nullable Provider<UserDto> derived from currentUserProvider. Since currentUserProvider can legitimately be null (no signed-in user), the provider throws 'User must be logged in to access this provider' to convert the nullable state into an explicit error whenever something watches authUserProvider while logged out.

Solutions

  1. Only watch/read authUserProvider from UI reachable exclusively after authentication (e.g. below a router guard that requires login).
  2. Replace with ref.watch(currentUserProvider) and handle the null case in the consumer.
  3. Make the provider nullable or return a UserDto? / AsyncValue to remove the throw.
  4. Ensure auth state is restored before building screens that depend on authUserProvider.

Example fix

// before
final user = ref.watch(authUserProvider);
// after
final user = ref.watch(currentUserProvider);
if (user == null) return const SignInPrompt();
// use non-null user here
Defensive patterns

Strategy: type-guard

Validate before calling

final maybeUser = ref.watch(currentUserProvider);
if (maybeUser == null) return; // or show login UI
final user = maybeUser;

Type guard

UserDto? userOrNull(Ref ref) => ref.watch(currentUserProvider);
bool hasUser(Ref ref) => ref.watch(currentUserProvider) != null;

Try / catch

try {
  final user = ref.read(authUserProvider);
  useUser(user);
} catch (e) {
  if (e.toString().contains('User must be logged in')) {
    navigateToLogin();
  } else {
    rethrow;
  }
}

Prevention

When it happens

Trigger: Any widget or provider calls ref.watch(authUserProvider) / ref.read(authUserProvider) while currentUserProvider is null — typically before login completes, after logout, or when reading it in app-startup code that runs before auth restoration.

Common situations: A screen that assumes authentication is mounted at app start before the session is restored; logout triggers a rebuild of a still-active widget watching authUserProvider; tests forget to seed a user before watching the provider.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/2e203ef222ef52bd. Report an issue: GitHub.

Appendix: source

Thrown at mobile/lib/providers/user.provider.dart:37

      await _userService.refreshMyUser();
    } catch (_) {}
  }

  @override
  void dispose() {
    unawaited(streamSub.cancel());
    super.dispose();
  }
}

final currentUserProvider = StateNotifierProvider<CurrentUserProvider, UserDto?>((ref) {
  return CurrentUserProvider(ref.watch(userServiceProvider));
});

final authUserProvider = Provider<UserDto>((ref) {
  final user = ref.watch(currentUserProvider);
  if (user == null) {
    throw Exception('User must be logged in to access this provider');
  }
  return user;
});

View on GitHub (pinned to e55ac299a4)