Scryer 0.17.0
Acknowledgements
Section titled “Acknowledgements”A big thanks to everyone who tested, filed issues, and kept pushing on the rough edges during the 0.17.0 cycle. This is the largest release Scryer has had. Most of it came out of feedback about the interface, about how much work the app did to find missing items, and about how painful it was to move a real Sonarr and Radarr setup across.
Highlights
Section titled “Highlights”A new Scryer interface
Section titled “A new Scryer interface”The web app has been rebuilt around one responsive shell instead of a collection of pages that each looked and behaved slightly differently. There’s a new header, a grouped sidebar, real mobile navigation, consistent focus states, and shared styling for panels, forms, tables, and dialogs. That shell now covers login, setup, the catalog, automation, integrations, system administration, and even error and loading states.
The whole app works on a phone now, not just the main pages.
Display preferences are now per-user: light or dark theme, regional or ISO dates, 24-hour time, & highlight color.
Personalized Discovery
Section titled “Personalized Discovery”Discovery is now a permanent part of Scryer rather than a one-off metadata lookup. The new discovery home page shows a ton of rails including: upcoming, new on streaming/physical, a personalized weekly rail, and genre, theme, collection-completion, and anime-aware rails. Detail views and “More Like This” recommendations carry enough identity, artwork, and permission context to add, request, or open the right title directly.
Filters cover content type, genre, theme, studio, year, and minimum rating. Anything duplicate, invalid, already in your library, or wrong for the facet is removed, and everything respects per-library permissions.
Global Search
Section titled “Global Search”The old route-command palette is gone, replaced by a single Global Search that works the same on desktop and mobile. Results can interleave titles already in your library, metadata results from outside it, and navigation, action, and settings commands.
All, In Library, Actions, and per-facet tabs combine with additive filters, and ranking accounts for exact, prefix, and keyword matches. Results either open a title you already manage or start the correct add or request flow for something you don’t, based on what the current library actually allows.
One catalog, one title workspace
Section titled “One catalog, one title workspace”Movies, series, and anime now share the same catalog and title-management model. Poster, poster-plus-table, and compact-table modes replace three separate implementations, and your choice is remembered per content scope. The standalone movie overview page is gone — movie detail now opens inline in the same title workspace used everywhere else.
That workspace brings monitoring, automatic and interactive search, refresh and scan, rename, history, blocklist, on-disk file inspection, primary-file selection, external subtitles, deletion previews, and external metadata links into one place. Bulk selection supports monitor, unmonitor, edit, and previewed deletion, including optional on-disk deletion with resumable job state.
Large libraries should feel noticeably better. Catalogs use server-side cursor pagination, projection-aware queries, abortable requests, infinite loading, and virtualized scroll restoration, and the first page is deliberately small instead of eagerly fetching hundreds of records. Filters cover monitored state, status, library, root, genre, theme, year, and minimum rating. Columns and sort keys include added date, year, runtime, status, root, popularity, resolution, HDR, audio codec, size, episode progress, and source-specific ratings. Sorting is now fixed for multi-lanugage (CJK aware).
Ratings are now source-branded, covering IMDb, Rotten Tomatoes critic and Popcornmeter, Metacritic critic and user, Letterboxd, TMDB, TVDB, Trakt, MyAnimeList, AniList, AniDB, and MDBList.
Indexer convergence replaces per-item Wanted scheduling
Section titled “Indexer convergence replaces per-item Wanted scheduling”This is the biggest behavioral change in the release. Scryer no longer builds and polls a separate search schedule for every missing item. Instead it tracks whether each relevant indexer has actually covered a missing or cutoff-upgrade scope.
An indexer only gets convergence credit after a real fired response — including a valid empty one. Disabled, skipped, deferred, and errored indexers don’t count. A scope is converged only once every currently routed indexer has covered the current criteria fingerprint, and any change to routing or criteria reopens it automatically. The fingerprint includes quality profile identity and version, required audio languages, and match identity; subtitle preferences deliberately don’t reopen acquisition coverage. Once a scope converges it returns to RSS monitoring.
Wanted is now organized as Missing, Upgrades, Pending, and History, and it shows you what’s actually happening: searching, converged or “Watching RSS”, deferred, hot or cold queue state, and which indexers are routed and covered. Missing and upgrade searches run as single-flight background jobs with processed, grabbed, and failed progress, and they can be canceled.
Underneath, one upstream scheduler now coordinates quotas, cooldowns, retry feedback, and jitter across all outbound clients. RSS is scheduled per indexer targeting 15-minute freshness, stretching to 60 minutes under low quota. Automatic searches also learn which identifier strategy works best per title, indexer, and facet, suppressing a strategy after three valid empty results when another one works and re-probing it a week later. Interactive searches are never suppressed by that learning.
Byparr indexer proxies
Section titled “Byparr indexer proxies”Indexers can now reference a managed Byparr challenge-solving proxy.
Improved Sonarr, Radarr, and Prowlarr import
Section titled “Improved Sonarr, Radarr, and Prowlarr import”Now supports multiple sonarr/radarr instances
Plugin SDK 3.6 and a native plugin host
Section titled “Plugin SDK 3.6 and a native plugin host”The supported SDK moves to 3.6, adding query facets, path and tag configuration fields, richer download context, archive-extractor contracts, and subtitle-sync command models. Underneath, Scryer replaced the Extism host dependency with a native Wasmtime host for the same Extism-PDK ABI.
Archive extraction and subtitle synchronization now run in sandboxed command hosts with read-only inputs, writable outputs, path and symlink escape protection, timeouts, and memory and output limits. Archive extraction is no longer bundled into the application — it’s selected dynamically by format, which means archived downloads stay blocked until you install and enable an Archive Extraction plugin. Scryer still owns archive-set discovery, first-volume selection, PAR2 recovery and repair preparation, destination validation, and the import itself.
Suspending a user’s login
Section titled “Suspending a user’s login”Administrators can now suspend and re-enable a user’s login without deleting the account or anything attached to it — password, passkeys, MFA enrollment, external account links, and permissions all survive. Suspending revokes active sessions and OAuth refresh grants and blocks password, passkey, and external-provider sign-in.
Scryer won’t let an administrator suspend their own login or the last usable full administrator. The built-in admin account can be suspended but not deleted, and recovery-admin access stays controlled by the environment. Permission editors also gained select-all and clear-all actions across application permissions, facets, and libraries.
Scheduled jobs and the download-queue poller now run under an internal System principal, so background work no longer depends on whichever administrator happened to configure it.
Faster, more observable library scans
Section titled “Faster, more observable library scans”Library enumeration, title matching, metadata hydration, and file analysis now stream progress instead of waiting for whole phases to finish. Walking and analysis share global concurrency limits, but each library can scan or cancel independently — even when several libraries belong to the same facet.
Scryer now records a source signature based on file modification state, so unchanged files skip repeat analysis. Duplicate files are represented as primary and additional copies, unreadable files stay pending rather than being falsely imported, and folder discovery ignores recycle, trash, cache, trailer, extras, featurette, trickplay, and Plex version paths.
Unix permissions and richer rename templates
Section titled “Unix permissions and richer rename templates”Media and library settings gained opt-in Unix permission application, with common file and folder mode presets, validated custom octal values, symbolic previews, file-mode derivation from folder mode, and optional group ownership. On Unix, hardlink import now requires the source UID to match the Scryer process UID; foreign-owned sources are copied instead, and destination ownership is verified.
Folder and filename templates are now edited separately, with facet-aware validation, autocomplete, and a live token reference. Templates support escaped literal braces, numeric padding, filter chaining, season_order, absolute_episode, truncate:N, and whitespace replacement.
Before You Upgrade
Section titled “Before You Upgrade”Back up first, and expect a longer first start
Section titled “Back up first, and expect a longer first start”The 0.17 database upgrade is materially heavier than a typical patch migration. Back up the datastore, leave migrations enabled, don’t interrupt the first start, and expect extra database, disk, and metadata-gateway activity while it settles.
Custom API clients must be updated
Section titled “Custom API clients must be updated”0.17 intentionally changes the GraphQL contract. Do not pair a 0.17 frontend with a 0.16 server, and regenerate or update any custom API clients and browser extensions before upgrading.
Misc Bugfixes and Improvements
Section titled “Misc Bugfixes and Improvements”- Downloads: SABnzbd now checks its queue and history after an ambiguous
addfileresponse instead of replaying the request or failing over, preventing duplicate submissions. - Downloads: Explicit
status: falseresponses from SABnzbd remain definitive rejections. - Downloads: Titles containing SABnzbd-illegal characters are normalized for reconciliation.
- Downloads: The compatible SABnzbd API path is resolved correctly.
- Downloads: Staged NZBs are reused across failover, cleaned up after final failure, and not refetched unnecessarily.
- Downloads: The router now sends only the NZB, torrent, or magnet forms the selected client declares compatible.
- Downloads: Proxy responses stay on their configured origin, are rechecked against outbound-target policy, and are capped at 64 MiB.
- Downloads: Torrent bodies are capped at 32 MiB and require a valid top-level bencoded
infodictionary. - Downloads: HTML challenge, login, and error pages are rejected before submission.
- Downloads: API errors now distinguish rejected, ambiguous, unavailable, plugin-required, canceled, and temporarily unavailable operations.
- Downloads: Temporary deferrals can include
Retry-After. - Downloads: Release queue actions use typed episode, episode-set, collection, series-movie, or title scope.
- Downloads: Pending force-grab no longer claims success when the server returns
grabbed: false. - Downloads: Weaver rejections with no queue item are handled as real rejections instead of malformed responses.
- Downloads: An accepted Weaver response that omits the queue item is now reported as temporarily unavailable.
- Downloads: qBittorrent API-key configurations are supported through the generic download-client settings flow, reusing saved keys for tests without exposing them to the browser.
- Acquisition: RSS evaluates the current derived target at match time and materializes state only for an anchored decision or grab.
- Acquisition: Completed submissions suppress an initial missing search without suppressing a scored upgrade; active submissions suppress both.
- Acquisition: Season packs are attempted only when at least two selected episodes share a season.
- Acquisition: A viable or pending pack prevents redundant episode searches, while a failed pack reopens and falls back to episode scopes.
- Acquisition: Failed downloads, rejected imports, replacements, and manual reopen events no longer delete convergence coverage.
- Acquisition: Standby candidates survive client snapshots and can be recovered without legacy wanted rows.
- Acquisition: Automatic episode fan-out deduplicates structured *nab shapes only when semantically equivalent, while text indexers retain distinct absolute-number,
SxxEyy, and season searches. - Acquisition: Indexer candidates share one deadline across scheduler admission, concurrency waits, rate limiting, queries, and fallbacks.
- Acquisition: An indexer that never actually fired is reported as skipped and receives no convergence credit.
- Acquisition: Anime movie and series-movie searches use the owning title’s tags and language context, fixing dual-audio inference.
- Acquisition: Cutoff-unmet and pending-release reads are paged and bounded, and due pending releases are processed before fresh RSS work.
- Library: Scan state is keyed by library as well as facet, fixing one library appearing busy because another in the same facet was scanning.
- Library: Title detail refreshes preserve already-loaded episode, file, and recommendation data and prune only entries that genuinely disappeared.
- Library: File deletion updates episode and series-movie maps consistently.
- Library: Specials headings localize correctly even when upstream labels are not English.
- Library: Same-title sibling duplication, clean-folder pollution, ambiguous leaf-path hints, and multiple-primary records are handled more defensively.
- Library: Movie evidence can use a stable direct-child scan instead of unnecessary recursion.
- Library: Folder discovery ignores recycle, trash, system, cache, trailer, extras, featurette, trickplay, Plex version, theme-music, and DOS 8.3 paths while retaining valid non-UTF-8 entries.
- Library: Symlinked folders are deduplicated and recursive depth remains bounded.
- Library: NFO matching no longer treats a bare movie or show
<id>as provider identity, prioritizing explicituniqueid, provider attributes, Jellyfin identity, and scan hints instead. - Library: Library roots preserve Unix
/, Windows drive roots, and UNC share roots while still normalizing ordinary trailing separators. - Library: Empty catalogs distinguish missing or invalid roots from a temporary validation outage, and existing content stays visible when a configured root is offline.
- Library: Multi-root scans share one session, and empty libraries report deterministic zero totals.
- Library: Legacy rows missing a source signature are backfilled without forcing unnecessary reanalysis.
- Import: Pending imports no longer race match, bind, and ignore mutations or create incomplete titles from identifier-only selections.
- Import: Import placement snapshots and revalidates the source and destination parent, retries transient copy failures, and verifies copied content before move cleanup.
- Import: Cleanup is refused after path replacement, and a destination whose ownership verification fails is removed.
- Import: Transfer progress is heartbeat-aware, and newly created folders receive their configured permissions.
- Import: Active import identity is scoped by client, system, and download identity; reused client item IDs clear stale terminal state.
- Import: Large client lookups are chunked, and uncataloged duplicate-file skips no longer suppress a later valid import.
- Import: Title create-or-get and pending-import binding are transactional and preserve identical external identities independently per library.
- Import: Stale pending-import rows and missing loose files no longer clear an existing title’s valid folder path.
- Import: Manual imports are persisted once and now surface persistence failures instead of reporting success.
- Import: An import-blocked item can be sent to manual review from Scryer’s tracked snapshot even after it disappears from the download client’s live queue.
- Import: Manual review can resolve an item whose original submission identity is unavailable.
- Import: Invalid rename-template tokens are rejected before save.
- Import: Upgrade housekeeping correctly handles encoded media roots and staged replacement cleanup.
- Validation: Automated imports now reject provably bad media, including ordinary movie and episode samples around 20 seconds, zero or indeterminate runtimes, unknown content below one minute, and files changed after probing.
- Validation: Short-form titles above their expected floor remain valid.
- Validation: Manually queued imports can bypass the automated sample gate, and forced manual replacement can intentionally accept a lower score.
- Validation: MediaInfo rescoring, user rules, and canonical analysis persistence run before final acceptance.
- Audio: Required-audio validation now distinguishes absence from uncertainty, rejecting only when every stream is resolved and proves absence.
- Audio: Uncertain evidence produces an
audio_language_warninginstead of a rejection. - Audio: Stream tags and unambiguous track-title tokens are normalized, codec tokens and ambiguous two-letter words are ignored, and
LATmaps to Latin-American Spanish. - Audio: Release-name hints can satisfy unresolved tracks, and
DUALconsistently means English plus the inferred original language for non-anime titles. - Audio: MediaInfo retains human-readable stream and track titles even when the language tag is missing or
und. - Subtitles: Subtitle scores are clamped to display percentages.
- Subtitles: Archive selection retains episode, language, and format ranking.
- Subtitles: Sync records alignment, split and no-split scores, selected frame-rate ratio, consistency, and an explicit skip reason.
- Subtitles: Enhanced subtitle sync reuses stored container, video, audio, subtitle, and chapter metadata instead of probing the media again.
- Subtitles: ZIP, 7z, and RAR subtitle bundles use the archive plugin, while TAR and supported single-file compression remain local.
- Subtitles: Subtitle searches and downloads now use the shared upstream scheduler, and automated fan-out omits deferred providers.
- Search: Search avoids stale and duplicate results after authorization changes and filters metadata identities already represented by any owner copy.
- Search: Adding or requesting a title refreshes autocomplete in the background without delaying the action or replacing it with a later refresh error.
- Search: Search no longer auto-opens over an existing dialog.
- Catalog: Poster failures degrade to a deterministic generated treatment instead of broken or unstable image slots.
- Catalog: Catalog sort and filter state respects library-view permissions and handles multilingual titles, CJK width, source ratings, and root validity consistently.
- Catalog: After a scan, poster catalogs refresh every loaded page instead of only the first, so older cards no longer go stale.
- Catalog: Catalog headers report the full title count and managed storage size.
- Artwork: Refreshes normalize relative and duplicate-separator URLs and commit processed bytes only if the title still points to the requested source.
- Artwork: Content-addressed blobs deduplicate identical images, reject digest conflicts, and wait for the last reference before collection.
- Artwork: Polluted local URLs and invalid variants are repaired through remote fallback and reprocessing.
- Artwork: Local and TMDB poster and backdrop URLs select appropriate variants while preserving cache-version behavior.
- Metadata: TVDB links use correct movie and series slug routes with a safe fallback.
- Metadata: Duplicate external title rematches are rejected.
- Metadata: AniBridge hydration normalizes MAL, AniList, AniDB, Kitsu, Simkl, TVDB, TMDB, IMDb, and Trakt identities and respects per-library title ownership.
- Requests: Media requests hydrate missing external identity, facet, artwork, and year before duplicate checks, so partial identifiers can’t bypass existing-library detection.
- Discovery: Opening a title workspace refreshes “More Like This” even when an older set is loaded, and a failed refresh no longer replaces current recommendations with an empty result.
- Discovery: Hero cards retain their full backdrop and overview after personalized subject resolution.
- Discovery: Owned items are excluded through normalized external identities, including movie-shaped items attached to series.
- Security: A stale authenticated token rejected by authless proof is cleared and retried through the logged-out proof flow instead of trapping bootstrap and login.
- Security: MFA-enrollment tokens are no longer accepted as ordinary authenticated sessions.
- Security: Authentication bootstrap is deduplicated and permission claims are normalized.
- Security: Rate-limited startup requests retry sanely, and login shows a specific rate-limit message.
- Security: Configuration MFA step-up state, expiry, and forced challenges are centralized so sensitive actions can’t reuse an expired token.
- Security: Security reauthentication uses the current signed-in username and requests only the password.
- Security: Jellyfin login now follows required MFA enrollment, including pending invites for an existing user.
- Security: Permission changes revoke prior tokens until re-login.
- Security: Library-scoped media and recycle-bin actions enforce the target library grant in addition to global capability.
- Security: Pending-import title search and resolution require
ManageTitleson the unmatched item’s library. - Security: Indexer-proxy management requires
ManageSystemSettings. - Security: Title-scoped interactive search requires
ManageTitles, while broader library or facet search requiresManageCatalogSettings. - Plugins: Descriptor-owned username, password, and API-key values are no longer overwritten by empty legacy fields.
- Plugins: Connection tests reuse omitted saved secrets, stored secrets can be cleared deliberately, and typed number, boolean, and tag values preserve their type.
- Plugins: Installation reports checksum, SDK metadata, and compatibility errors with actionable messages.
- Plugins: Registry refreshes are coalesced and briefly suppressed after completion so subscriptions don’t launch redundant work.
- Plugins: Download-client drafts deep-clone dynamic config and save only against the selected provider’s declared fields.
- Plugins: Catalog status is cached rather than probed on every read, so installed plugins stay manageable during catalog outages.
- Plugins: Incompatible uninstalled entries are hidden, and the highest compatible release is selected from the complete release set.
- Indexers: Deleting a managed indexer parent or uninstalling its provider now removes the full child tree and its routing entries.
- Indexers: Startup removes orphaned managed children left by an interrupted or older uninstall.
- Integrations: Disk-space health checks are correctly Unix-only, and multi-library health roots are deduplicated by normalized path.
- Integrations: SMG enrollment retries narrowly defined transient gateway failures, honors bounded
Retry-Afterdelays, and returns permanent failures immediately. - Integrations: Removing the last local or remote path mapping now saves an empty mapping instead of leaving a stale row behind.
- Database: Daily SQLite maintenance runs a full
VACUUMonly when at least 2,000 pages and 10% of the database are free. - Database: Unreferenced image blobs are pruned in bounded batches.
- Database: SQLite can read timestamps written by
CURRENT_TIMESTAMP, including fractional seconds. - Database: Busy retries match only the real
SQLITE_BUSYandSQLITE_LOCKEDcode families instead of delaying unrelated errors whose numbers start with the same digit. - Database: SQLite restore clears portable and reset-only tables, imports the bundle, validates foreign keys and row counts, and commits as one immediate transaction.
- Database: PostgreSQL uses the same dependency-ordered reset and import model.
- Runtime: Startup ownership repair continues past vanished entries, unreadable submounts, and individual chown failures, then reports the aggregate count and first error.
- Runtime: Workflow rows left queued, running, or discovering by a process restart are marked failed with an interruption reason, so jobs and acquisition views can’t remain active forever.
- Runtime: Scheduler state is persisted and flushed during graceful shutdown.
- Release parsing: Episode ranges such as
S3.01-02,S3-01-02, andSeason 1 - 001-020now parse correctly. - Release parsing: Fused daily dates, month-name dates in either order, fused and decimal frame rates, CAMRip/HDCAM, DTS-HD-MA hyphenation, accented tokens, and canonical edition casing are recognized.
- Release parsing: Ambiguous AMZN and NF WEBRip names normalize to WEB-DL.
- Release parsing: Dolby Vision by itself no longer implies HDR, while explicit HDR10, HDR10+, and DV-HDR still do.
- Release parsing: Eight-digit bracket tokens remain checksums, and ordinary title numbers, color depth, and PROPER/REPACK revisions are no longer misclassified as frame rate, season data, or editions.
- Release parsing: TRaSH Guides streaming-service alias generation rejects digit, one-letter, and generic source tokens, alternation fragments, and rename-template artifacts that previously produced false aliases.
- UI: Routine form-login denials of the authless proof probe log at debug instead of flooding warning logs.
- UI: Quality-profile background refetches use an apply epoch and preserve an operator’s in-progress draft.
- UI: Scan and job status use authoritative terminal state, so finished work no longer appears active.
- UI: History, file, and subtitle dates follow the selected account format.
- UI: Title history consumes the semantic
itemspayload and canonical event types. - UI: Recycle-bin failures distinguish quarantine from successful deletion instead of displaying a false success.
- UI: Rego diagnostics compensate for the hidden import line, and post-processing scripts receive the correct shell-language editor.
- UI: Rename templates preserve escaped literal braces and apply
truncate:Nand chained filters in the documented order. - UI: Setup path selection distinguishes files from folders, validates fresh media paths before continuing, and allows revisiting completed steps.
- UI: Title actions expose the correct Monitor or Unmonitor label and pressed state.
- UI: On-disk subtitle badges open the actual track list instead of showing a non-functional count.
- UI: Settings connection tests emit one result notification.
- UI: Profile passkeys wait for effective authentication settings and ignore stale responses.
- UI: Plugin install and upgrade cards settle once without duplicate terminal feedback.
- UI: Catalog view choices remain available on mobile instead of being forced back to posters.