gitbutlerapp/gitbutler · warning

Failed to fetch from RSS feed:

Error message

Failed to fetch from RSS feed:

What it means

The web app fetches its YouTube playlist JSON from an API; on a non-ok response or a thrown fetch/JSON error it warns and falls back to getGitButlerPlaylistFallback(), a hardcoded curated list keyed by playlistId. The page always renders a playlist, at the cost of serving stale videos whenever the fetch path fails.

Source

Thrown at apps/web/src/lib/youtube.ts:108

export async function fetchPlaylistVideos(playlistId: string): Promise<YouTubePlaylist> {
	try {
		const response = await fetch(`${env.PUBLIC_APP_HOST}api/youtube/playlist`, {
			// Add timeout to prevent hanging
			signal: AbortSignal.timeout(10000),
		});

		if (response.ok) {
			const data = (await response.json()) as { videos: APIYouTubeVideo[] };
			const videos = data.videos.map(mapAPIToYouTubeVideo);
			return {
				id: playlistId,
				title: "GitButler Feature Updates",
				description: "Latest GitButler tutorials, feature demonstrations, and updates",
				videos,
			};
		}
	} catch (error) {
		console.warn("Failed to fetch from RSS feed:", error);
	}

	// Fallback to hardcoded playlist data for the specific GitButler playlist
	return getGitButlerPlaylistFallback(playlistId);
}

/**
 * Fallback data with actual GitButler video information
 * This can be updated manually when new videos are added to the playlist
 */
function getGitButlerPlaylistFallback(playlistId: string): YouTubePlaylist {
	const videos: YouTubeVideo[] = [
		{
			id: "NOYK7LTFvZM",
			title: "Using Cursor Hooks for automatic version control",
			description:
				"Here we demonstrate how to use GitButler with the new Cursor Hooks functionality to automate creating branches for chat sessions and committing work as you go with smart commit messages. Never lose a step again.",
			thumbnail: "https://img.youtube.com/vi/NOYK7LTFvZM/maxresdefault.jpg",

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Verify network and the API response status in devtools, then retry when back online
  2. If videos look stale, update the hardcoded fallback list — it is curated manually by design
  3. Fix or escalate the API if it consistently returns non-ok
  4. Cache the last successful response client-side so the fallback stays fresher
Defensive patterns

Strategy: fallback

Validate before calling

async function reachable(url: string): Promise<boolean> {
	try {
		const res = await fetch(url, { method: "HEAD" });
		return res.ok;
	} catch {
		return false;
	}
}

Type guard

function isNetworkFailure(e: unknown): boolean {
	return e instanceof TypeError; // fetch rejects with TypeError on network-level failure
}

Try / catch

try {
	return await fetchPlaylist(playlistId);
} catch (error) {
	console.warn("Failed to fetch from RSS feed:", error);
	return getGitButlerPlaylistFallback(playlistId); // degrade, never throw
}

Prevention

When it happens

Trigger: fetch() rejects (offline, DNS failure, timeout), the API returns non-200 (4xx/5xx), or response.json() throws on a malformed body — each lands in the catch at apps/web/src/lib/youtube.ts:108 and activates the hardcoded fallback.

Common situations: Offline browsing or flaky mobile networks; the playlist API rate-limited or down; CDN or edge misconfiguration; an API response shape change breaking mapAPIToYouTubeVideo.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/d3812b180308ece7. Report an issue: GitHub.