{"record":{"id":"87d615164418614a","repo":"tonhowtf/omniget","slug":"study-music-yt-error","errorCode":null,"errorMessage":"[study-music] yt error:","messagePattern":"\\[study-music\\] yt error:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/study-music-youtube-components/YoutubeError.svelte","lineNumber":28,"sourceCode":"    onFallback?: () => void;\n  };\n  let { error, onRetry, fallbackLabel, onFallback }: Props = $props();\n\n  let humanized = $state<string>(\"\");\n  let showDetails = $state(false);\n\n  async function resolve(err: string) {\n    try {\n      const res = await studyYoutubeHumanizeError({ error: err });\n      humanized = res.humanized;\n    } catch {\n      /* keep default */\n    }\n  }\n\n  $effect(() => {\n    void resolve(error);\n    console.warn(\"[study-music] yt error:\", error);\n  });\n</script>\n\n<div class=\"yt-error\" role=\"alert\">\n  <svg\n    viewBox=\"0 0 24 24\"\n    width=\"22\"\n    height=\"22\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"1.6\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    aria-hidden=\"true\"\n  >\n    <circle cx=\"12\" cy=\"12\" r=\"10\" />\n    <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n    <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"16.01\" />","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src/lib/study-music-youtube-components/YoutubeError.svelte#L10-L46","documentation":"YouTube track playback/lookup failed in the study-music player and the error component was mounted. A $effect calls resolve(error) to normalize the raw error for display and logs the raw value with console.warn.","triggerScenarios":"A YouTube source fails during resolve or streaming (invalid video id, unavailable/private video, expired stream URL, network or API error) and YoutubeError receives it as the error prop.","commonSituations":"Deleted or age/region-restricted videos, expiring googlevideo stream URLs, yt-dlp/backend extractor breakage after YouTube changes, or network offline.","solutions":["Read the logged raw error to classify availability vs expiry vs network","Refresh the stream URL (player refresh_url path) and retry playback","Skip the track or enable auto-skip-on-error","Open the video in browser via the component's link to confirm availability"],"exampleFix":"// before\n$effect(() => {\n  void resolve(error);\n  console.warn(\"[study-music] yt error:\", error);\n});\n// after\n$effect(() => {\n  const resolved = resolve(error);\n  console.warn(\"[study-music] yt error:\", resolved?.kind ?? \"unknown\", error);\n});","handlingStrategy":"fallback","validationCode":"if (!videoId || !/^[\\w-]{11}$/.test(videoId)) throw new Error(\"invalid youtube video id\");","typeGuard":"function isResolvableYtTrack(t: unknown): t is YtTrack {\n  return !!t && typeof t === \"object\" && typeof (t as YtTrack).youtube_video_id === \"string\" && (t as YtTrack).youtube_video_id.length === 11;\n}","tryCatchPattern":"try {\n  await ytPlayer.play(track);\n} catch (e) {\n  console.warn(\"[study-music] yt error:\", e);\n  await refreshTrackUrl(track); // refresh_url path\n  skipToNextTrack();\n}","preventionTips":["Refresh expired stream URLs before each playback attempt","Enable auto-skip-on-error","Validate video ids and availability up front","Keep the yt extractor backend updated"],"tags":["youtube","audio-player","error-ui"],"backgroundTag":"upstream-api-error","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}