immich-app/immich · error · Exception
User must be logged in to video
Error message
User must be logged in to video
What it means
Thrown by the timelineServiceProvider override in the Video page when currentUserProvider is null. The video timeline needs a user id (timelineFactoryProvider.video(user.id)), so an unauthenticated session makes the provider throw during initialization. It means the Video page was built without a logged-in user.
Solutions
- Ensure authentication before navigating to the video page.
- Make the page await the resolved auth AsyncValue instead of reading a possibly-null user.
- Re-authenticate (token refresh or login) on this error and retry navigation.
- Return a login prompt widget from the override when the user is null.
Example fix
// before
final user = ref.watch(currentUserProvider);
if (user == null) {
throw Exception('User must be logged in to video');
}
// after
final user = ref.watch(currentUserProvider);
if (user == null) {
return const SizedBox.shrink(); // or redirect to login
} Defensive patterns
Strategy: try-catch
Validate before calling
final user = ref.watch(currentUserProvider);
if (user == null) {
context.go('/login');
return;
} Type guard
bool isAuthenticated(User? u) => u != null && u.id.isNotEmpty;
Try / catch
try {
final timeline = ref.watch(timelineServiceProvider);
// play video timeline
} catch (e) {
if (e.toString().contains('User must be logged in')) {
context.go('/login');
} else {
rethrow;
}
} Prevention
- Route to video pages only through authenticated guards
- Resolve auth state before user-scoped provider overrides run
- Proactively refresh sessions on app resume
- Fallback to a login screen when user is null
When it happens
Trigger: Opening the video page before login completes, after logout/token expiry, or when auth state restoration races with page navigation so currentUserProvider reads null.
Common situations: Expired session token; deep link to a video opened pre-login; app resumed from background after the session was invalidated.
Related errors
- User must be logged in to access recently taken
- User must be logged in to access trash
- User must be logged in to access archive
- User must be logged in to access archive
- User must be logged in to access favorite
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/9139097fba4754e2.
Report an issue: GitHub.
Appendix: source
Thrown at mobile/lib/presentation/pages/video.page.dart:21
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/presentation/widgets/timeline/timeline.widget.dart';
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/widgets/common/mesmerizing_sliver_app_bar.dart';
@RoutePage()
class VideoPage extends StatelessWidget {
const VideoPage({super.key});
@override
Widget build(BuildContext context) {
return ProviderScope(
overrides: [
timelineServiceProvider.overrideWith((ref) {
final user = ref.watch(currentUserProvider);
if (user == null) {
throw Exception('User must be logged in to video');
}
final timelineService = ref.watch(timelineFactoryProvider).video(user.id);
ref.onDispose(timelineService.dispose);
return timelineService;
}),
],
child: Timeline(appBar: MesmerizingSliverAppBar(title: context.t.videos)),
);
}
}
View on GitHub (pinned to e55ac299a4)