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 exception is thrown by the recently-added page's timelineServiceProvider override when currentUserProvider yields null. The recently-taken timeline is user-scoped (timelineFactoryProvider.recentlyAdded(user.id)), so it cannot be built without a logged-in user; the provider throws this exception instead. It indicates the page was reached before authentication resolved.

Solutions

  1. Show a loading/login screen until currentUserProvider emits a user before rendering any timeline tab.
  2. Persist and restore the session on startup so currentUser is available at first build.
  3. Add a router redirect guarding all timeline pages behind authentication.
  4. Confirm the auth provider is correctly initialized/overridden in the root ProviderScope.

Example fix

// before
final timelineService = ref.watch(timelineServiceProvider);
// after
final user = ref.watch(currentUserProvider);
if (user == null) return const LoginPage();
final timelineService = ref.watch(timelineServiceProvider);
Defensive patterns

Strategy: validation

Validate before calling

final user = ref.read(currentUserProvider);
if (user == null) {
  context.go('/login');
  return;
}

Type guard

bool isSignedIn(User? user) => user != null && user.id.isNotEmpty;

Try / catch

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

Prevention

When it happens

Trigger: Opening the recently added page while currentUserProvider is null — first frame before auth initialization, logout clearing the user, or a route pushed without the login gate.

Common situations: App cold start landing on the recently-taken tab before session restore completes; auth token expiring silently so the user becomes null while the tab stays mounted; forgetting to initialize the auth provider in a test/dev build.

Related errors


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

Appendix: source

Thrown at mobile/lib/presentation/pages/recently_added.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 RecentlyAddedPage extends StatelessWidget {
  const RecentlyAddedPage({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).recentlyAdded(user.id);
          ref.onDispose(timelineService.dispose);
          return timelineService;
        }),
      ],
      child: Timeline(appBar: MesmerizingSliverAppBar(title: context.t.recently_added)),
    );
  }
}

View on GitHub (pinned to e55ac299a4)