{"record":{"id":"168677cc2e9198e4","repo":"iawia002/lux","slug":"can-t-match-gif-content-downloadable-url","errorCode":null,"errorMessage":"can't match gif content downloadable url","messagePattern":"can't match gif content downloadable url","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/reddit/reddit.go","lineNumber":141,"sourceCode":"\t\t\t\tStreams: map[string]*extractors.Stream{\n\t\t\t\t\t\"default\": {\n\t\t\t\t\t\tParts: []*extractors.Part{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tURL:  imgURL,\n\t\t\t\t\t\t\t\tSize: size,\n\t\t\t\t\t\t\t\tExt:  \"jpg\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSize: size,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tURL: url,\n\t\t\t},\n\t\t}, nil\n\t} else if utils.MatchOneOf(html, `https:\\/\\/preview\\.redd\\.it\\/.*gif`) != nil {\n\t\tgifURL := utils.MatchOneOf(html, `https:\\/\\/preview\\.redd\\.it\\/.*?\\.gif\\?format=mp4.*?\"`)[0]\n\t\tif gifURL == \"\" {\n\t\t\treturn nil, errors.New(\"can't match gif content downloadable url\")\n\t\t}\n\n\t\tgifURL = strings.ReplaceAll(gifURL, \"&amp;\", \"&\")\n\t\tgifURL = strings.ReplaceAll(gifURL, \"\\\"\", \"\")\n\n\t\tsize, err := request.Size(gifURL, \"reddit.com\")\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"can't get video size\")\n\t\t}\n\n\t\tstreams := map[string]*extractors.Stream{\n\t\t\t\"default\": {\n\t\t\t\tParts: []*extractors.Part{\n\t\t\t\t\t{\n\t\t\t\t\t\tURL:  gifURL,\n\t\t\t\t\t\tSize: size,\n\t\t\t\t\t\tExt:  \"mp4\",\n\t\t\t\t\t},","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/reddit/reddit.go#L123-L159","documentation":"In the Reddit extractor's GIF branch: the page matched 'preview\\.redd\\.it/.*gif', so it captures the full 'https://preview.redd.it/...gif?format=mp4...' URL from the HTML. If that capture comes back empty, extraction fails. Like the mp4 branch, the guard indexes [0] directly — a nil MatchOneOf panics before this check, so the error only fires for an empty-string capture.","triggerScenarios":"Reddit changed the preview URL shape for gif posts (different host like v.redd.it or i.redd.it, dropped '?format=mp4', changed query ordering) so `https:\\/\\/preview\\.redd\\.it\\/.*?\\.gif\\?format=mp4.*?\"` no longer captures content.","commonSituations":"Site markup drift on Reddit's preview CDN links; posts converted from gif to native video between the og:video check and the gif branch; HTML-escaped URLs (&amp;) altering the match.","solutions":["Fetch the post HTML and search for 'preview.redd.it' to see the actual URL format now served","Update the gif capture regex in extractors/reddit/reddit.go to match the current preview URL shape","Nil-guard the MatchOneOf result before indexing [0] so markup changes produce this error instead of a panic","Retry once — Reddit serves different markup variants across requests"],"exampleFix":"// before\ngifURL := utils.MatchOneOf(html, `https:\\/\\/preview\\.redd\\.it\\/.*?\\.gif\\?format=mp4.*?\"`)[0]\nif gifURL == \"\" {\n    return nil, errors.New(\"can't match gif content downloadable url\")\n}\n\n// after\ngifMatch := utils.MatchOneOf(html, `https:\\/\\/preview\\.redd\\.it\\/.*?\\.gif\\?format=mp4.*?\"`)\nif gifMatch == nil || gifMatch[0] == \"\" {\n    return nil, errors.New(\"can't match gif content downloadable url\")\n}\ngifURL := gifMatch[0]","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"reddit extractor panicked (gif branch markup change): %v\", r)\n    }\n}()\n_, err = reddit.Extract(url, opts)\nif err != nil && strings.Contains(err.Error(), \"can't match gif content\") {\n    // preview.redd.it URL shape changed: skip and report\n}","preventionTips":["Wrap reddit extraction in recover — indexing MatchOneOf[0] without a nil check can panic","Retry once on this error: Reddit serves markup variants","Track preview.redd.it URL format changes in your monitoring"],"tags":["reddit","regex","html-parsing","index-out-of-range"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}