Summary
When Gelato live search is enabled, /Users/{userId}/Items?SearchTerm=... can return synthetic Stremio/Gelato GUIDs for search results. Those IDs are not always resolvable by Jellyfin detail/playback endpoints such as /Users/{userId}/Items/{id} or /Items/{id} unless an insert path has already materialized the item.
A related playback issue is that generated MediaSourceInfo entries may mark addon/debrid HTTP URLs as direct-playable and expose them to clients. In self-hosted setups those URLs can be internal Docker/service URLs (for example an internal addon reverse proxy), so remote clients try to direct-play an unreachable URL instead of proxying through Jellyfin.
Repro shape
Environment observed locally:
- Jellyfin 10.11.x
- Gelato 0.26.15.1
- Live search enabled (
DisableSearch=false)
- Stremio/AIOStreams-backed catalogs/search
Steps:
- Search via Jellyfin API:
GET /Users/{userId}/Items?SearchTerm=The%20Phoenician%20Scheme&Recursive=true&Limit=8&Fields=ProviderIds
- Gelato intercepts the search and returns a synthetic result ID.
- Open details:
GET /Users/{userId}/Items/{syntheticId}
- The detail request can return
404 because the synthetic ID is only in Gelato's search/meta cache and not a canonical Jellyfin item ID.
For already-materialized items, search should prefer the canonical Jellyfin item ID. Example observed with a canonical item already in the library:
- Search result synthetic ID returned first.
- Canonical Jellyfin item existed and
/Users/{userId}/Items/{canonicalId} worked.
/Users/{userId}/Items/{syntheticId} failed.
For remote playback, MediaSourceInfo.Path in API responses can contain an internal addon URL and SupportsDirectPlay=true, which lets clients bypass Jellyfin and time out off-LAN.
Expected behavior
- Search results should prefer an existing canonical Jellyfin item when provider IDs match, instead of returning a synthetic ID.
- Synthetic search IDs should be resolvable by item detail/playback insert filters when no canonical item exists yet.
- Addon/debrid HTTP stream URLs should not be advertised as direct-playable to clients when Jellyfin is expected to proxy them.
Local mitigation tested
A local patch fixed the observed failures by:
- In
SearchActionFilter.ConvertMetasToDtos, calling manager.FindExistingItem(baseItem) and returning the existing item DTO when present.
- Extending insertable action/user-id detection for detail/playback routes where user id may be an action/route argument instead of only a claim/query param.
- Marking Gelato stream media sources as not direct-playable and stubbing URLs in DTO/playback responses so clients proxy through Jellyfin.
After patching locally:
- Live search still returned in ~0.4-1.1s for tested titles.
- Existing items returned canonical IDs.
- Live-only search results could be opened and materialized instead of 404ing.
- Public Jellyfin
/Videos/{itemId}/stream.mkv?... returned HTTP 200 and started streaming, while API responses no longer exposed the internal addon URL as a direct-playable source.
Summary
When Gelato live search is enabled,
/Users/{userId}/Items?SearchTerm=...can return synthetic Stremio/Gelato GUIDs for search results. Those IDs are not always resolvable by Jellyfin detail/playback endpoints such as/Users/{userId}/Items/{id}or/Items/{id}unless an insert path has already materialized the item.A related playback issue is that generated
MediaSourceInfoentries may mark addon/debrid HTTP URLs as direct-playable and expose them to clients. In self-hosted setups those URLs can be internal Docker/service URLs (for example an internal addon reverse proxy), so remote clients try to direct-play an unreachable URL instead of proxying through Jellyfin.Repro shape
Environment observed locally:
DisableSearch=false)Steps:
GET /Users/{userId}/Items?SearchTerm=The%20Phoenician%20Scheme&Recursive=true&Limit=8&Fields=ProviderIdsGET /Users/{userId}/Items/{syntheticId}404because the synthetic ID is only in Gelato's search/meta cache and not a canonical Jellyfin item ID.For already-materialized items, search should prefer the canonical Jellyfin item ID. Example observed with a canonical item already in the library:
/Users/{userId}/Items/{canonicalId}worked./Users/{userId}/Items/{syntheticId}failed.For remote playback,
MediaSourceInfo.Pathin API responses can contain an internal addon URL andSupportsDirectPlay=true, which lets clients bypass Jellyfin and time out off-LAN.Expected behavior
Local mitigation tested
A local patch fixed the observed failures by:
SearchActionFilter.ConvertMetasToDtos, callingmanager.FindExistingItem(baseItem)and returning the existing item DTO when present.After patching locally:
/Videos/{itemId}/stream.mkv?...returned HTTP 200 and started streaming, while API responses no longer exposed the internal addon URL as a direct-playable source.