{"record":{"id":"10f3fa471a9477f4","repo":"jackwener/OpenCLI","slug":"failed-to-fetch-channel-data","errorCode":null,"errorMessage":"Failed to fetch channel data","messagePattern":"Failed to fetch channel data","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/channel.js","lineNumber":203,"sourceCode":"              }\n            }\n          }\n        }\n\n        return {\n          name: metadata.title || '',\n          channelId: metadata.externalId || browseId,\n          handle: metadata.vanityChannelUrl?.split('/').pop() || '',\n          description: (metadata.description || '').substring(0, 500),\n          subscribers: subscriberCount,\n          url: metadata.channelUrl || 'https://www.youtube.com/channel/' + browseId,\n          keywords: metadata.keywords || '',\n          recentVideos,\n        };\n      })()\n    `);\n        if (!data || typeof data !== 'object')\n            throw new CommandExecutionError('Failed to fetch channel data');\n        if (data.error)\n            throw new CommandExecutionError(String(data.error));\n        const result = data;\n        const videos = result.recentVideos;\n        delete result.recentVideos;\n        // Channel info as field/value pairs + recent videos as table\n        const rows = Object.entries(result).map(([field, value]) => ({\n            field,\n            value: String(value),\n        }));\n        if (videos && videos.length > 0) {\n            rows.push({ field: '---', value: '--- Recent Videos ---' });\n            for (const v of videos) {\n                rows.push({ field: v.title, value: `${v.duration} | ${v.views} | ${v.url}` });\n            }\n        }\n        return rows;\n    },","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/channel.js#L185-L221","documentation":"After evaluating the channel-data extraction script in the YouTube page, the command checks that a non-null object came back; otherwise it throws 'Failed to fetch channel data'. It guards against the probe returning nothing usable (null/undefined/primitive).","triggerScenarios":"The in-page script returned null because the current page is not a channel page, the channel doesn't exist/was terminated, or YouTube served a consent/login interstitial instead of channel data.","commonSituations":"Passing a video URL or handle that doesn't resolve to a channel; deleted/terminated channels; YouTube A/B layouts where the extraction script finds no data; age/region restrictions.","solutions":["Verify the URL/channel argument resolves to an existing channel page in a browser","Ensure you are logged in (run auth) since some channels require a session","Update the extraction script for current YouTube channel-page markup","Retry — transient interstitials can be bypassed on a second load"],"exampleFix":"// before\nawait cli youtube channel 'https://www.youtube.com/@not-a-channel'\n// after\nawait cli youtube channel 'https://www.youtube.com/@existinghandle'","handlingStrategy":"validation","validationCode":"// confirm the target is a live channel page before scraping\nconst res = await fetch(channelUrl, { method: 'HEAD' });\nif (!res.ok || res.url.includes('oops')) throw new Error('Channel page unavailable');","typeGuard":"function isChannelData(d) {\n  return d !== null && typeof d === 'object' && !('error' in d);\n}","tryCatchPattern":"try {\n  await cli.youtube.channel(url);\n} catch (e) {\n  if (/Failed to fetch channel data/.test(e.message)) {\n    console.error('No channel data returned; verify the channel URL and login state');\n  } else throw e;\n}","preventionTips":["Validate the channel URL/handle resolves in a browser first","Authenticate before scraping channels that need a session","Handle YouTube A/B layout changes by updating the extraction script","Retry on transient interstitial pages"],"tags":["youtube","scraping","extraction"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}