Kareadita/Kavita · error · KavitaException

no-user

no-user

Error message

no-user

What it means

Thrown by StreamService.CreateDashboardStreamFromSmartFilter when GetUserByIdAsync(userId, AppUserIncludes.DashboardStreams) returns null — the authenticated user's account cannot be loaded. The message is translated server-side before throwing ('User does not exist'). StreamController.AddDashboard does not catch KavitaException, so it reaches ExceptionMiddleware and returns HTTP 500 with that translated text.

Source

Thrown at Kavita.Services/StreamService.cs:50

    {
        return await unitOfWork.UserRepository.GetDashboardStreams(userId, visibleOnly, ct);
    }

    public async Task<IEnumerable<SideNavStreamDto>> GetSidenavStreams(int userId, bool visibleOnly = true, CancellationToken ct = default)
    {
        return await unitOfWork.UserRepository.GetSideNavStreams(userId, visibleOnly, ct);
    }

    public async Task<IEnumerable<ExternalSourceDto>> GetExternalSources(int userId, CancellationToken ct = default)
    {
        return await unitOfWork.AppUserExternalSourceRepository.GetExternalSources(userId, ct);
    }

    public async Task<DashboardStreamDto> CreateDashboardStreamFromSmartFilter(int userId, int smartFilterId,
        CancellationToken ct = default)
    {
        var user = await unitOfWork.UserRepository.GetUserByIdAsync(userId, AppUserIncludes.DashboardStreams, ct);
        if (user == null) throw new KavitaException(await localizationService.TranslateAsync(userId, "no-user"));

        var smartFilter = await unitOfWork.AppUserSmartFilterRepository.GetById(smartFilterId, ct);
        if (smartFilter == null) throw new KavitaException(await localizationService.TranslateAsync(userId, "smart-filter-doesnt-exist"));

        var stream = user.DashboardStreams.FirstOrDefault(d => d.SmartFilter?.Id == smartFilterId);
        if (stream != null) throw new KavitaException(await localizationService.TranslateAsync(userId, "smart-filter-already-in-use"));

        var maxOrder = user!.DashboardStreams.Max(d => d.Order);
        var createdStream = new AppUserDashboardStream()
        {
            Name = smartFilter.Name,
            IsProvided = false,
            StreamType = DashboardStreamType.SmartFilter,
            Visible = true,
            Order = maxOrder + 1,
            SmartFilter = smartFilter
        };

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Force a re-login / token refresh; if the account was deleted, the user must be recreated.
  2. Verify the user still exists (admin: check Users list) before retrying.
  3. On the client, treat a persistent 'no-user' as an auth failure and redirect to login.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await api.post(`/api/stream/add-dashboard-stream?smartFilterId=${id}`);
} catch (e) {
  // HTTP 500 translated 'User does not exist': session/account is invalid.
  await auth.refreshOrLogout();
}

Prevention

When it happens

Trigger: POST /api/stream/add-dashboard-stream?smartFilterId=N when the userId derived from the JWT no longer maps to a user (account deleted between login and the call, or an invalid/stale token).

Common situations: Admin deleted the user while their session was still active; token issued for a removed account; user table restored from a backup that lacks this user; race between auth and the repository read.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/a6ee25a00c73b65b. Report an issue: GitHub.