Skip to content

Keep yt-dlp's search extractors in packaged builds - #693

Merged
thcp merged 1 commit into
mainfrom
fix/692-search-extractors
Sep 25, 2026
Merged

thcp merged 1 commit into
mainfrom
fix/692-search-extractors

Conversation

@thcp

@thcp thcp commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Fixes #692

Packaging prunes yt-dlp from ~940 extractors down to nine and writes a new registry from the EXPORTS list in scripts/prune_ytdlp_extractors.py. That list named the URL extractors and left out YoutubeSearchIE, YoutubeSearchURLIE and SoundcloudSearchIE.

The modules themselves ship. youtube/ and soundcloud.py are both there, the registry simply never imports those three classes, so nothing registers them. Search then asked for the youtube:search extractor, found none, and yt-dlp answered:

ERROR: No suitable extractor found for URL ytsearch8:purple rain

Pasting a link kept working the whole time, because that route matches YoutubeIE. Running from a source checkout also kept working, because nothing is pruned there, which is why this was invisible in development.

All three search tabs were affected, not just the one in the report. Measured against an installed 0.17.2 runtime:

Route Before After
YouTube songs No suitable extractor 8 items
YouTube playlists No suitable extractor 8 items
SoundCloud songs No suitable extractor 8 items

Why it shipped green

verify() asserted that a watch URL, a youtu.be URL and a SoundCloud track URL still match. A watch URL and a ytsearch8: target are matched by different classes out of the same module, so every one of those assertions passed for a registry with no search in it at all.

What changed

  • The three search classes are in EXPORTS.
  • verify() now fails at packaging time if YouTube or SoundCloud search is not registered.
  • Two tests read the app's own allowlists (_ALLOWED_EXTRACTORS, _ALLOWED_PLAYLIST_EXTRACTORS, search._EXTRACTORS), then build the real search targets through _target() and check each one resolves under the allowlist it runs with. A new allowlist entry cannot get ahead of the prune again.

Both tests fail against the old script, with allowlisted but not shipped: ['soundcloud:search', 'youtube:search', 'youtube:search_url'], and pass with the fix.

Verified

A clean yt-dlp pruned by this script, then the backend booted against it and POST /api/search called for each route: 8 results each, top hit "Nirvana - Come As You Are (Official Music Video)". Full file: 9 tests pass.

Note for the release

This lands in the runtime pack, not the app shell, so it reaches people only through a new pack. An existing install keeps the broken registry until it downloads one.

Packaging prunes yt-dlp down to YouTube and SoundCloud and writes a new
extractor registry. That registry left out YoutubeSearchIE,
YoutubeSearchURLIE and SoundcloudSearchIE, so every search in a packaged
build failed with "No suitable extractor found for URL ytsearch8:...".
Source runs never prune, which is why it only showed up in releases.

The build-time verify now fails if search is not registered, and two tests
check the app's own extractor allowlists and search targets against a
pruned tree, so a new allowlist entry cannot get ahead of the prune again.

Fixes #692
@thcp
thcp marked this pull request as ready for review September 25, 2026 09:02
@thcp
thcp merged commit c08e852 into main Sep 25, 2026
12 checks passed
@thcp
thcp deleted the fix/692-search-extractors branch September 25, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: stemdeck.api search failed

1 participant