{"record":{"id":"f175c763df124c0c","repo":"slymnoyann/hey-1","slug":"could-not-generate-thumbnails","errorCode":null,"errorMessage":"Could not generate thumbnails","messagePattern":"Could not generate thumbnails","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/components/Composer/ChooseThumbnail.tsx","lineNumber":125,"sourceCode":"      );\n    } else {\n      setVideoThumbnail({\n        ...videoThumbnail,\n        uploading: false,\n        url: thumbnail.decentralizedUrl\n      });\n    }\n  };\n\n  const generateThumbnails = async (fileToGenerate: File) => {\n    try {\n      setIsGenerating(true);\n      const thumbnailArray = await generateVideoThumbnails(\n        fileToGenerate,\n        THUMBNAIL_GENERATE_COUNT\n      );\n      if (!thumbnailArray.length) {\n        throw new Error(\"Could not generate thumbnails\");\n      }\n\n      const thumbnailList: Thumbnail[] = [];\n      for (const thumbnailBlob of thumbnailArray) {\n        thumbnailList.push({ blobUrl: thumbnailBlob, decentralizedUrl: \"\" });\n      }\n      setThumbnailList(thumbnailList);\n      handleSelectThumbnail(DEFAULT_THUMBNAIL_INDEX, thumbnailList);\n    } catch {\n      setThumbnailList([]);\n      setVideoThumbnail(DEFAULT_VIDEO_THUMBNAIL);\n      toast.error(\"Failed to generate video thumbnails\");\n    } finally {\n      setIsGenerating(false);\n    }\n  };\n\n  useEffect(() => {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/slymnoyann/hey-1/blob/88c8f9d55340d57a37846ff72f55c2c604e3a566/src/components/Composer/ChooseThumbnail.tsx#L107-L143","documentation":"Thrown by generateThumbnails in ChooseThumbnail.tsx when the video thumbnail generation pipeline returns an empty array. It wraps generateVideoThumbnails (which decodes the selected video file and extracts THUMBNAIL_GENERATE_COUNT frames); an empty result means zero frames could be extracted from the file.","triggerScenarios":"Selecting a video file that the browser cannot decode via the video element (unsupported codec/container), a 0-byte or corrupted video, a file with no video track (audio-only), or metadata loaded but seek/frame capture failing (e.g. duration NaN) so generateVideoThumbnails resolves with [].","commonSituations":"Users upload HEVC/AVI/MKV files that Chrome/Firefox can't play; a truncated upload or aborted recorder blob; browsers with restrictive codec support (Safari vs Chromium differences); very large files where decoding times out before frames are captured.","solutions":["Verify the video file plays in an <video> element in the same browser before generating thumbnails; if it doesn't, reject the file at selection time with a codec error","Check file.size > 0 and file.type starts with 'video/' before calling generateThumbnails","If codecs are the issue, require transcoding to H.264/MP4 (or WebM) before upload","Catch this error in the UI and prompt the user to pick a different file or retry"],"exampleFix":"// before\nconst thumbnailArray = await generateVideoThumbnails(fileToGenerate, THUMBNAIL_GENERATE_COUNT);\nif (!thumbnailArray.length) {\n  throw new Error(\"Could not generate thumbnails\");\n}\n\n// after: validate decodability first\nconst canDecode = await new Promise((resolve) => {\n  const v = document.createElement(\"video\");\n  v.preload = \"metadata\";\n  v.onloadedmetadata = () => resolve(Number.isFinite(v.duration) && v.duration > 0);\n  v.onerror = () => resolve(false);\n  v.src = URL.createObjectURL(fileToGenerate);\n});\nif (!canDecode) {\n  throw new Error(\"Video format not supported by your browser\");\n}\nconst thumbnailArray = await generateVideoThumbnails(fileToGenerate, THUMBNAIL_GENERATE_COUNT);\nif (!thumbnailArray.length) {\n  throw new Error(\"Could not generate thumbnails\");\n}","handlingStrategy":"validation","validationCode":"const canExtractFrames = async (file: File) => {\n  if (!file.type.startsWith(\"video/\") || file.size === 0) return false;\n  return new Promise((resolve) => {\n    const v = document.createElement(\"video\");\n    v.preload = \"metadata\";\n    v.onloadedmetadata = () => resolve(Number.isFinite(v.duration) && v.duration > 0);\n    v.onerror = () => resolve(false);\n    v.src = URL.createObjectURL(file);\n  });\n};","typeGuard":"const isDecodableVideo = (file: File): boolean =>\n  file.size > 0 && /^video\\//.test(file.type);","tryCatchPattern":"try {\n  await generateThumbnails(file);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Could not generate thumbnails\") {\n    // prompt user: file may use an unsupported codec; suggest MP4/H.264\n  }\n  throw e;\n}","preventionTips":["Validate file.type is video/* and size > 0 at file-pick time","Pre-check the file loads in a video element with a finite duration before generating thumbnails","Recommend/require H.264 MP4 or WebM outputs from any client-side recording pipeline"],"tags":["video","thumbnails","media-decoding","browser-compatibility"],"backgroundTag":"video-decode-unsupported-codec","analyzedSha":"88c8f9d55340d57a37846ff72f55c2c604e3a566","analyzedAt":"2026-08-28T16:20:43.640Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}