immich-app/immich · error · Exception

User must be logged in to access recently taken

Error message

User must be logged in to access recently taken

What it means

This error is thrown by the timelineServiceProvider override in the Recently Taken page's build method. When the Riverpod currentUserProvider resolves to null, the page cannot construct a TimelineService (which requires a user id), so it throws synchronously during provider initialization. It signals that the screen was rendered without an authenticated user.

Solutions

  1. Ensure the user is authenticated before routing to this page (redirect unauthenticated sessions to the login screen).
  2. Gate the page on an auth-ready AsyncValue so it waits for currentUserProvider to resolve instead of reading null.
  3. On receiving this error, refresh/restore the session and re-login, then reload the page.
  4. Handle the null case gracefully in the override (show a login prompt widget instead of throwing).

Example fix

// before
final user = ref.watch(currentUserProvider);
if (user == null) {
  throw Exception('User must be logged in to access recently taken');
}
// after
final user = ref.watch(currentUserProvider);
if (user == null) {
  return const SizedBox.shrink(); // or render a 'please log in' widget
}
Defensive patterns

Strategy: try-catch

Validate before calling

final user = ref.watch(currentUserProvider);
if (user == null || !authService.isSessionValid) {
  // route to login before accessing the page
  return;
}

Type guard

bool isAuthenticated(User? u) => u != null && u.id.isNotEmpty;

Try / catch

try {
  final timeline = ref.watch(timelineServiceProvider);
  // render page
} catch (e) {
  if (e.toString().contains('User must be logged in')) {
    context.go('/login');
  } else {
    rethrow;
  }
}

Prevention

When it happens

Trigger: Navigating to the Recently Taken page while currentUserProvider yields null — e.g. before login completes, after session token expiry with a stale cached user, or during a race where auth state is still loading when the page builds.

Common situations: Deep-links or push notifications opening the page before login; the app restoring the tab after logout; auth API returning no user due to expired tokens or server logout.

Related errors


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

Appendix: source

Thrown at mobile/lib/presentation/pages/recently_taken.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 RecentlyTakenPage extends StatelessWidget {
  const RecentlyTakenPage({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 access recently taken');
          }

          final timelineService = ref.watch(timelineFactoryProvider).remoteAssets(user.id);
          ref.onDispose(timelineService.dispose);
          return timelineService;
        }),
      ],
      child: Timeline(appBar: MesmerizingSliverAppBar(title: context.t.recently_taken)),
    );
  }
}

View on GitHub (pinned to e55ac299a4)