diff --git a/tests/test_video_downloads_page.py b/tests/test_video_downloads_page.py
index fb6a005d..4d6bf3a6 100644
--- a/tests/test_video_downloads_page.py
+++ b/tests/test_video_downloads_page.py
@@ -50,6 +50,17 @@ def test_drawer_renders_the_rich_tmdb_fields():
assert "trailer_url" in _JS and "providers" in _JS
+def test_youtube_open_button_links_to_youtube_not_a_show_page():
+ # regression: the open-show button ran parseInt(youtube_id) → opened a random library
+ # show (e.g. id 3) or a broken link. youtube cards must open a YouTube link instead.
+ open_block = _JS.split("var openBtn")[1].split("var stateBtn")[0]
+ assert "dlType(d.kind) === 'youtube'" in open_block
+ assert "youtube.com/watch?v=" in open_block
+ # the data-vdpg-open (open-show) path must NOT be taken for youtube
+ assert "data-vdpg-open" in open_block # still there for movie/show
+ assert open_block.index("'youtube'") < open_block.index("data-vdpg-open") # youtube branch first
+
+
def test_drawer_has_episode_youtube_and_availability_blocks():
assert "vdpg-dr-ytthumb" in _JS # youtube big thumbnail header
assert "vdpg-dr-ep" in _JS and "vdpg-dr-epstill" in _JS # episode still + block
diff --git a/webui/static/video/video-downloads-page.js b/webui/static/video/video-downloads-page.js
index 0486b7c5..995e39af 100644
--- a/webui/static/video/video-downloads-page.js
+++ b/webui/static/video/video-downloads-page.js
@@ -154,9 +154,15 @@
var lab = q('label'); if (lab.textContent !== labelTxt) lab.textContent = labelTxt;
var act = q('actions');
- var openBtn = d.media_id ? '' : '';
+ // youtube videos aren't TMDB titles — the open button links to YouTube, not a show page
+ // (parseInt on a video id was opening a random library show / a broken link).
+ var openBtn = !d.media_id ? ''
+ : (dlType(d.kind) === 'youtube'
+ ? '' + OPEN_SVG + ''
+ : '');
var stateBtn = active
? ''
: isFail(d.status)