Kareadita/Kavita · warning · KavitaException
You cannot use the name of a system provided stream
Error message
You cannot use the name of a system provided stream
What it means
Thrown by FilterController.ValidateAndSaveFilterUpsert when the requested name matches (case-insensitive) a system-provided stream name in Defaults.DefaultStreams. Caught and returned as HTTP 400 BadRequest. Note the source comment: DefaultStreams names are localization keys (e.g. 'on-deck'), so collisions are rare in practice.
Source
Thrown at Kavita.Server/Controllers/FilterController.cs:129
var encodedString = SmartFilterHelper.Encode(dto);
await ValidateAndSaveFilterUpsert(dto.Name!, encodedString, dto.EntityType);
return Ok();
}
catch (KavitaException ex)
{
return BadRequest(ex.Message);
}
}
private async Task ValidateAndSaveFilterUpsert(string filterName, string encodedFilter, FilterEntityType entityType)
{
var user = (await unitOfWork.UserRepository.GetUserByIdAsync(UserId, AppUserIncludes.SmartFilters))!;
if (string.IsNullOrWhiteSpace(filterName)) throw new KavitaException("Name must be set");
if (Defaults.DefaultStreams.Any(s => s.Name.Equals(filterName, StringComparison.InvariantCultureIgnoreCase)))
{
// NOTE: This checks against localization keys (on-deck), so this case will almost never happen
throw new KavitaException("You cannot use the name of a system provided stream");
}
var existingFilter = user.SmartFilters.FirstOrDefault(s => s.Name.Equals(filterName, StringComparison.InvariantCultureIgnoreCase));
if (existingFilter != null)
{
// Update the filter
existingFilter.Filter = encodedFilter;
unitOfWork.AppUserSmartFilterRepository.Update(existingFilter);
}
else
{
existingFilter = new AppUserSmartFilter()
{
Name = filterName,
Filter = encodedFilter,
EntityType = entityType
};
user.SmartFilters.Add(existingFilter);View on GitHub (pinned to 9c3e540000)
Solutions
- Choose a filter name that does not collide with any Defaults.DefaultStreams name.
- On the client, reserve/block the known system stream names in the name input.
- If you added a new DefaultStream, expect its key to become a reserved filter name.
Example fix
// before
await ValidateAndSaveFilterUpsert("on-deck", encoded, entityType);
// after
await ValidateAndSaveFilterUpsert("My On-Deck", encoded, entityType); Defensive patterns
Strategy: validation
Validate before calling
var reserved = Defaults.DefaultStreams.Select(s => s.Name)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
if (reserved.Contains(name))
return BadRequest("Name reserved for a system stream"); Type guard
static bool IsReservedStreamName(string name)
=> Defaults.DefaultStreams.Any(s =>
s.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); Try / catch
try { await ValidateAndSaveFilterUpsert(name, enc, type); }
catch (KavitaException ex) { return BadRequest(ex.Message); } Prevention
- Block known DefaultStreams names in the client name field.
- Suffix reserved keys if a similar name is needed (e.g. 'on-deck-2').
- Re-check reserved names after upgrading, as defaults can change.
When it happens
Trigger: Naming a smart filter exactly the same as a built-in/default stream name like 'on-deck' (case-insensitive).
Common situations: User picks a name that coincides with a system stream key; localization key reuse. Almost never triggers because system stream names are localization keys rather than display names.
Related errors
- {comparison} is not applicable for {fieldName}
- Name must be set
- invalid-metadata-provider
- smart-filter-doesnt-exist
- smart-filter-already-in-use
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/1a767a77ba32b6a0.
Report an issue: GitHub.