Kareadita/Kavita · error · OpdsException
OPDS feed generation is not implemented for Person smart fil
Error message
OPDS feed generation is not implemented for Person smart filters
What it means
Thrown by OpdsService.ResolveSmartFilter when the decoded smart filter has FilterEntityType.Person. The OPDS feed generation switch statement only handles Series and ReadingList entity types; Person is an explicit unimplemented branch that throws immediately. This is a known feature gap: Kavita's smart filter engine supports Person-based filters internally, but the OPDS catalog feed builder has no rendering path for them.
Source
Thrown at Kavita.Services/OpdsService.cs:426
(SeriesFilterV2Dto) decodedFilter, ct: ct);
var seriesMetadatas = await unitOfWork.SeriesRepository.GetSeriesMetadataForIdsAsync(series.Select(s => s.Id), ct);
foreach (var seriesDto in series)
{
feed.Entries.Add(CreateSeries(seriesDto, seriesMetadatas.First(s => s.SeriesId == seriesDto.Id), apiKey, prefix, baseUrl));
}
AddPagination(feed, series, $"{prefix}{apiKey}/smart-filters/{request.EntityId}/");
break;
case FilterEntityType.ReadingList:
var readingLists = await unitOfWork.ReadingListRepository.GetBrowseReadingListDtos(userId, (ReadingListFilterDto) decodedFilter, userParams, ct);
foreach (var readingList in readingLists)
{
feed.Entries.Add(CreateReadingListFeedEntry(readingList, prefix, apiKey, baseUrl));
}
AddPagination(feed, readingLists, $"{prefix}{apiKey}/smart-filters/{request.EntityId}/");
break;
case FilterEntityType.Person:
throw new OpdsException("OPDS feed generation is not implemented for Person smart filters");
case FilterEntityType.Annotation:
throw new OpdsException("OPDS feed generation is not implemented for Annotation smart filters");
}
return feed;
}
public async Task<Feed> GetSeriesFromCollection(OpdsItemsFromEntityIdRequest request, CancellationToken ct = default)
{
var userId = UnpackRequest(request, out var apiKey, out var prefix, out var baseUrl);
var collectionId = request.EntityId;
var tag = await unitOfWork.CollectionTagRepository.GetCollectionAsync(collectionId, ct: ct);
if (tag == null || (tag.AppUserId != userId && !tag.Promoted))
{
throw new OpdsException(await localizationService.TranslateAsync(userId, "collection-doesnt-exist"));
}
View on GitHub (pinned to 9c3e540000)
Solutions
- Avoid accessing Person-type smart filters through the OPDS feed; use the Kavita web UI instead, where Person filters are fully supported.
- Recreate the filter as a Series-type filter that filters by Person attributes, which will render correctly in OPDS.
- Request the feature from Kavita's issue tracker if Person OPDS feeds are needed.
- In the OPDS client, hide or exclude Person-type filters from the smart-filter listing to prevent users from navigating into them.
- If building a custom OPDS integration, check the filter's EntityType via the API before requesting the feed and gracefully skip Person types.
Example fix
// If you control the OPDS client, skip Person/Annotation filters:
// Before calling ResolveSmartFilter, check the filter type:
// GET /api/opds/{apiKey}/smart-filters/{filterId} (metadata)
// if filter.EntityType == 'Person': skip with a user-friendly message
// Alternatively, recreate the filter targeting Series with a Person condition:
// SmartFilter { EntityType: Series, Statements: [{ Field: Writers, Value: 'Name' }] } Defensive patterns
Strategy: validation
Validate before calling
// Before requesting a Person-type smart filter feed, check the EntityType:
// var filter = await unitOfWork.AppUserSmartFilterRepository.GetById(filterId, ct);
// if (filter == null) return NotFound();
// var decoded = SmartFilterHelper.Decode(filter.Filter);
// if (decoded.EntityType == FilterEntityType.Person)
// {
// return BadRequest("Person smart filters are not available in OPDS.");
// }
// var feed = await opdsService.ResolveSmartFilter(request, ct); Type guard
// C# type/enum guard for the filter entity type:
static bool IsOpdsSupportedFilterType(FilterEntityType type)
=> type is FilterEntityType.Series or FilterEntityType.ReadingList; Try / catch
// try { var feed = await opdsService.ResolveSmartFilter(request, ct); }
// catch (OpdsException ex) when (ex.Message.Contains("not implemented"))
// {
// // This filter type is not supported in OPDS.
// // Show a user-friendly message; do not retry.
// return BadRequest("This smart filter type is not supported in OPDS feeds.");
// } Prevention
- Do not create Person-type smart filters if OPDS access is expected; use Series-type filters instead.
- In OPDS clients, filter the smart-filter listing to exclude Person and Annotation types.
- Educate users that only Series and ReadingList smart filters are OPDS-accessible.
- When building OPDS integrations, check EntityType before requesting the feed.
- File a feature request if Person OPDS feed support is needed.
When it happens
Trigger: A user creates a Person-type smart filter in the Kavita web UI (filtering by writer, artist, character, etc.). They then attempt to open that filter's feed via an OPDS reader at {apiKey}/smart-filters/{filterId}. SmartFilterHelper.Decode identifies the EntityType as Person, and the switch falls into the throw branch.
Common situations: A user has Person-type smart filters alongside their Series/ReadingList filters, and their OPDS reader auto-crawls all filter feeds. The OPDS reader cached a link to a Person filter before OPDS Person-feed support existed (it still doesn't).
Related errors
- OPDS feed generation is not implemented for Annotation smart
- smart-filter-doesnt-exist
- collection-doesnt-exist
- no-library-access
- reading-list-restricted
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/0e0028d543edcc01.
Report an issue: GitHub.