{"record":{"id":"b19c73e2d70791bd","repo":"tonhowtf/omniget","slug":"study-music-yt-refresh-failed","errorCode":null,"errorMessage":"[study-music] yt refresh failed","messagePattern":"\\[study-music\\] yt refresh failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/study-music/player-store.svelte.ts","lineNumber":1659,"sourceCode":"      console.info(\"[study-music] yt refresh start\", { videoId });\n      const res = await studyYoutubePlayer({ videoId });\n      const url = pickBestYoutubeAudio(res);\n      const videoUrl = pickBestYoutubeVideo(res);\n      if (!url) throw new Error(\"refresh returned no audio format\");\n      const wasPaused = this.audio.paused;\n      const t = this.audio.currentTime;\n      this.audio.crossOrigin = null;\n      this.audio.src = url;\n      this.audio.currentTime = t;\n      this.youtubeVideoUrl = videoUrl;\n      if (!wasPaused) await this.audio.play();\n      this.youtubeChapters = res.chapters ?? this.youtubeChapters;\n      this.youtubeRefreshFailureCount = 0;\n      this.scheduleYoutubeRefresh(videoId, res.expires_at);\n      console.info(\"[study-music] yt refresh ok\", { videoId, expires_at: res.expires_at });\n    } catch (err) {\n      this.youtubeRefreshFailureCount += 1;\n      console.warn(\n        \"[study-music] yt refresh failed\",\n        { videoId, attempt: this.youtubeRefreshFailureCount },\n        err,\n      );\n      if (\n        this.youtubeRefreshFailureCount >= MusicPlayerStore.YOUTUBE_REFRESH_MAX_FAILURES\n      ) {\n        try {\n          this.audio.pause();\n        } catch {\n          /* ignore */\n        }\n        const track = this.currentTrack;\n        if (track) {\n          this.setError(classifyPlayerError(\"auth_expired\", \"youtube\", track.id));\n        }\n        this.youtubeRefreshFailureCount = 0;\n        return;","sourceCodeStart":1641,"sourceCodeEnd":1677,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src/lib/study-music/player-store.svelte.ts#L1641-L1677","documentation":"Warning logged when the periodic YouTube stream-URL/chapters refresh for the current video fails. The store increments youtubeRefreshFailureCount and keeps retrying; once failures reach YOUTUBE_REFRESH_MAX_FAILURES it gives up (typically stopping playback).","triggerScenarios":"The scheduled refresh's pluginInvoke/backend resolve of the YouTube video fails: expired video, network outage, rate limiting, or the video being removed/region-blocked.","commonSituations":"Long listening sessions where the stream URL expires and re-resolution hits rate limits; offline/VPN interruptions; deleted or age-restricted videos.","solutions":["Check network connectivity and retry playback","Skip to a different track if the video was removed or is region-blocked","Check backend YouTube extraction (e.g. ytdl/yt-dlp) is up to date — 403/429 responses indicate extractor staleness or rate limiting","Restart playback to reset the failure counter and force a fresh resolve"],"exampleFix":"// before\n} catch (err) {\n  this.youtubeRefreshFailureCount += 1;\n// after\n} catch (err) {\n  if (isRateLimitError(err)) await backoff(MusicPlayerStore.YOUTUBE_REFRESH_BACKOFF_MS);\n  this.youtubeRefreshFailureCount += 1;","handlingStrategy":"retry","validationCode":"if (!navigator.onLine) { scheduleYoutubeRefresh(videoId, Date.now() + 30_000); return; }","typeGuard":"function isRefreshResult(v: unknown): v is { url: string; expires_at: number; chapters?: unknown[] } { return typeof v === \"object\" && v !== null && \"url\" in v && \"expires_at\" in v; }","tryCatchPattern":"try { const res = await refreshStream(videoId); ... } catch (err) { if (attempt < MAX_FAILURES) { await backoff(attempt); return scheduleYoutubeRefresh(videoId, Date.now() + backoffMs(attempt)); } this.setError(classifyPlayerError(err, \"youtube\", videoId)); }","preventionTips":["Refresh the stream URL before expires_at, not after playback breaks","Apply exponential backoff instead of fixed-interval retries","Validate videos exist before adding them to playlists","Keep the YouTube extractor/backend up to date to avoid 403/429s"],"tags":["youtube","network","retry"],"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"}