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
- Only watch/read authUserProvider from UI reachable exclusively after authentication (e.g. below a router guard that requires login).
- Replace with ref.watch(currentUserProvider) and handle the null case in the consumer.
- Make the provider nullable or return a UserDto? / AsyncValue to remove the throw.
- 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
- Prefer watching currentUserProvider (nullable) and handle null explicitly
- Place authUserProvider consumers only inside authenticated route subtrees
- Seed a user in tests before watching authUserProvider
- Use router guards so logged-out states never build screens depending on it
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
- Authentication required
- Cannot derive a mobile build number from
- Cast session is not established
- Forbidden
- Incorrect email or password
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)