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
- Force a re-login / token refresh; if the account was deleted, the user must be recreated.
- Verify the user still exists (admin: check Users list) before retrying.
- 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
- Handle 'no-user' as an auth failure: refresh the token or redirect to login.
- Recreate the account if it was admin-deleted.
- Do not retry the same call with the same invalid token.
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
- errors.oidc.no-account
- smart-filter-doesnt-exist
- smart-filter-already-in-use
- not-authenticated
- User is not authenticated
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/a6ee25a00c73b65b.
Report an issue: GitHub.