Kareadita/Kavita · warning · KavitaException
smart-filter-doesnt-exist
smart-filter-doesnt-exist
Error message
smart-filter-doesnt-exist
What it means
Thrown by StreamService.CreateDashboardStreamFromSmartFilter when AppUserSmartFilterRepository.GetById(smartFilterId) returns null — the smart filter does not exist (or does not belong to the user). The message is translated to 'Smart Filter doesn't exist'. StreamController.AddDashboard does not catch it, so it surfaces via ExceptionMiddleware as HTTP 500 with that text.
Source
Thrown at Kavita.Services/StreamService.cs:53
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
};
user.DashboardStreams.Add(createdStream);
unitOfWork.UserRepository.Update(user);
await unitOfWork.CommitAsync(ct);View on GitHub (pinned to 9c3e540000)
Solutions
- Use a smartFilterId from the user's current smart-filter list.
- Refresh the smart filters in the UI before offering 'add to dashboard'.
- If the filter was deleted, recreate it, then add the stream.
Defensive patterns
Strategy: validation
Validate before calling
const filters = await api.getSmartFilters();
if (!filters.some(f => f.id === smartFilterId)) {
showError('Smart Filter not found');
return;
}
await api.post(`/api/stream/add-dashboard-stream?smartFilterId=${smartFilterId}`); Type guard
function isKnownFilterId(id: number, filters: { id: number }[]): boolean {
return filters.some(f => f.id === id);
} Prevention
- Offer 'add to dashboard' only for filters in the user's current list.
- Refresh smart filters after delete operations.
- Drop stale smartFilterIds from deep links by validating before use.
When it happens
Trigger: POST /api/stream/add-dashboard-stream?smartFilterId=N with a deleted, invalid, or other-user smart filter id.
Common situations: Stale smartFilterId cached in the UI after the filter was deleted; deep link/bookmark with an old id; cross-user id confusion.
Related errors
- smart-filter-already-in-use
- dashboard-stream-doesnt-exist
- external-source-doesnt-exist
- {comparison} is not applicable for {fieldName}
- Name must be set
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/75ebdddc65ff3554.
Report an issue: GitHub.