immich-app/immich · error · Exception

User must be logged in to view person timeline

Error message

User must be logged in to view person timeline

What it means

This exception is thrown by the person page's timelineServiceProvider override when currentUserProvider is null. The person timeline requires both the logged-in user id and the person id (timelineFactoryProvider.person(user.id, _person.id)), so a null user makes the service unconstructible and the provider throws. It means the person timeline page was built without an authenticated session.

Solutions

  1. Gate person routes on a non-null currentUser via a router redirect to the login page.
  2. Complete auth restoration before restoring the navigation stack that contains the person page.
  3. Ensure currentUserProvider is backed by the live auth stream and updated on login/logout.
  4. Handle auth errors in the stream so a transient failure does not leave currentUser null while the app is signed in.

Example fix

// before
Navigator.of(context).push(PersonPage.route(person));
// after
final user = ref.read(currentUserProvider);
if (user == null) {
  context.go('/login');
} else {
  Navigator.of(context).push(PersonPage.route(person));
}
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: Reading timelineServiceProvider on the person page while currentUserProvider is null — auth stream not yet emitted, session cleared by logout/expiry, or navigation to a person before login finishes.

Common situations: Tapping a person notification/deep link before the app finishes sign-in; session expiry while browsing a person timeline; app state restoration pushing this page ahead of the login gate.

Related errors


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

Appendix: source

Thrown at mobile/lib/presentation/pages/person.page.dart:82

          },
          onEditBirthday: () async {
            await handleEditBirthday(context);
            ContextHelper(context).pop();
          },
          birthdayExists: _person.birthDate != null,
        );
      },
    );
  }

  @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 view person timeline');
          }

          final timelineService = ref.watch(timelineFactoryProvider).person(user.id, _person.id);
          ref.onDispose(timelineService.dispose);
          return timelineService;
        }),
      ],
      child: Timeline(
        appBar: PersonSliverAppBar(
          person: _person,
          onNameTap: () => handleEditName(context),
          onBirthdayTap: () => handleEditBirthday(context),
          onShowOptions: () => showOptionSheet(context),
        ),
      ),
    );
  }
}

View on GitHub (pinned to e55ac299a4)