{"record":{"id":"5428b462b0eeca26","repo":"pear-devs/pear-desktop","slug":"plugins-downloader-backend-feedback-video-id-not-f","errorCode":null,"errorMessage":"plugins.downloader.backend.feedback.video-id-not-found","messagePattern":"plugins\\.downloader\\.backend\\.feedback\\.video-id-not-found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/plugins/downloader/main/index.ts","lineNumber":353,"sourceCode":") {\n  const sendFeedback = (message: unknown, progress?: number) => {\n    if (!playlistFolder) {\n      sendFeedback_(win, message);\n      if (progress && !isNaN(progress)) {\n        win.setProgressBar(progress);\n      }\n    }\n  };\n\n  sendFeedback(t('plugins.downloader.backend.feedback.downloading'), 2);\n\n  let id: string | null;\n  if (isId) {\n    id = idOrUrl;\n  } else {\n    id = getVideoId(idOrUrl);\n    if (typeof id !== 'string')\n      throw new Error(\n        t('plugins.downloader.backend.feedback.video-id-not-found'),\n      );\n  }\n\n  let info: YTMusic.TrackInfo | YT.VideoInfo = await yt.music.getInfo(id);\n\n  if (!info) {\n    throw new Error(\n      t('plugins.downloader.backend.feedback.video-id-not-found'),\n    );\n  }\n\n  const metadata = getMetadata(info);\n  if (metadata.album === 'N/A') {\n    metadata.album = '';\n  }\n\n  metadata.trackId = trackId;","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/pear-devs/pear-desktop/blob/1e2aac5706c870c93ed74ba8727ae8390d3b0fa5/src/plugins/downloader/main/index.ts#L335-L371","documentation":"The downloader plugin's downloadSong accepts either a YouTube video ID or URL. When the input is not an ID-shaped string, it runs it through getVideoId(); if that cannot extract a video ID from the URL, it throws this localized 'video ID not found' error before any network fetch happens.","triggerScenarios":"Passing a malformed or non-YouTube URL (e.g. a Spotify/SoundCloud link, a truncated youtube.com URL, a playlist-only URL without v= param); passing a string that neither matches the ID pattern nor parses as a video URL; URLs with extra whitespace or unicode characters that break the parser.","commonSituations":"Users pasting links from other platforms into the download box; clipboard truncation; YouTube URL format changes (e.g. shorts/music smart URLs) not handled by the installed youtube-ext version; passing an empty string.","solutions":["Verify the input is a valid YouTube watch/music/shorts URL or an 11-char ID before calling downloadSong","Trim the input and reject empty strings in the UI layer","Update the downloader plugin / youtube-ext dependency so getVideoId understands current YouTube URL shapes","If you already have the ID, pass it directly (isId path) instead of a URL"],"exampleFix":"// before\nawait downloader.downloadSong userInput);\n\n// after\nconst trimmed = userInput.trim();\nif (!/^[\\w-]{11}$/.test(trimmed) && !/youtube\\.com|youtu\\.be/.test(trimmed)) {\n  return notify('Please paste a valid YouTube link or ID');\n}\nawait downloader.downloadSong(trimmed);","handlingStrategy":"validation","validationCode":"const YT_URL = /(?:youtube\\.com|youtu\\.be|youtube\\.googleapis\\.com)/;\nconst isUsable = (s: string) =>\n  /^[\\w-]{11}$/.test(s.trim()) || YT_URL.test(s.trim());","typeGuard":"const isYouTubeIdOrUrl = (s: string): s is string =>\n  /^[\\w-]{11}$/.test(s) || /(?:youtube\\.com\\/watch|youtu\\.be\\/|youtube\\.com\\/shorts\\/)/.test(s);","tryCatchPattern":"try { await downloadSong(input); } catch (e) { if (t('plugins.downloader.backend.feedback.video-id-not-found') === e.message || /video-id-not-found/.test(e.message)) notify('Invalid YouTube link'); else throw e; }","preventionTips":["Validate/trim pasted links in the UI before calling downloadSong","Prefer extracting and passing the 11-char ID directly when you have it","Update the downloader plugin when YouTube URL formats change"],"tags":["downloader","youtube","url-parsing","validation","user-input"],"backgroundTag":"invalid-url-input","analyzedSha":"1e2aac5706c870c93ed74ba8727ae8390d3b0fa5","analyzedAt":"2026-08-27T20:01:08.614Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}