iawia002/lux · error

can't match mp4 content downloadable url

Error message

can't match mp4 content downloadable url

What it means

In the Reddit extractor's HLS branch: the page's og:video meta tag matched 'HLSPlaylist', so it tries to capture the video id from 'https://v.redd.it/(.+?)/HLSPlaylist'. If the captured group comes back empty, the extractor cannot build the audio URL (redditMP4API + id + audioURLPart) and fails. Note the guard is weak: if the second MatchOneOf returns nil, indexing [1] panics before this check ever runs — the error only covers the empty-capture case.

Source

Thrown at extractors/reddit/reddit.go:55

func New() extractors.Extractor {
	return &extractor{}
}

func (e *extractor) Extract(url string, option extractors.Options) ([]*extractors.Data, error) {
	html, err := request.Get(url, referer, nil)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	// set thread number to 1 manually to avoid http 412 error
	option.ThreadNumber = 1

	title := utils.MatchOneOf(html, `<title>(.+?)<\/title>`)[1]

	if utils.MatchOneOf(html, `meta property="og:video" content=.*HLSPlaylist`) != nil {
		mp4URL := utils.MatchOneOf(html, `https://v.redd.it/(.+?)/HLSPlaylist`)[1]
		if mp4URL == "" {
			return nil, errors.New("can't match mp4 content downloadable url")
		}

		audioURL := fmt.Sprintf("%s%s%s", redditMP4API, mp4URL, audioURLPart)
		size, err := request.Size(audioURL, referer)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		audioPart := &extractors.Part{
			URL:  audioURL,
			Size: size,
			Ext:  "mp3",
		}

		streams := make(map[string]*extractors.Stream, len(resMap))
		for res, urlParts := range resMap {
			resURL := fmt.Sprintf("%s%s%s", redditMP4API, mp4URL, urlParts)
			size, err := request.Size(resURL, referer)
			if err != nil {

View on GitHub (pinned to dd00f6d258)

Solutions

  1. Fetch the URL manually and inspect the og:video meta tag to see the actual URL shape being served
  2. Update the `https://v.redd.it/(.+?)/HLSPlaylist` regex in extractors/reddit/reddit.go to match the current markup
  3. If the MatchOneOf can return nil, guard it before indexing [1] to convert a potential panic into this error
  4. Retry the extraction — Reddit A/B-tests markup, so a fresh fetch may serve the old shape

Example fix

// before
mp4URL := utils.MatchOneOf(html, `https://v.redd.it/(.+?)/HLSPlaylist`)[1]
if mp4URL == "" {
    return nil, errors.New("can't match mp4 content downloadable url")
}

// after (avoid panic on nil match, same error)
mp4Match := utils.MatchOneOf(html, `https://v.redd.it/(.+?)/HLSPlaylist`)
if mp4Match == nil || mp4Match[1] == "" {
    return nil, errors.New("can't match mp4 content downloadable url")
}
Defensive patterns

Strategy: try-catch

Try / catch

defer func() {
    if r := recover(); r != nil {
        err = fmt.Errorf("reddit extractor panicked (likely markup change): %v", r)
    }
}()
_, err = reddit.Extract(url, opts)
if err != nil && strings.Contains(err.Error(), "can't match mp4 content") {
    // Reddit markup drift: report upstream, skip URL
}

Prevention

When it happens

Trigger: Reddit changed how v.redd.it HLS URLs appear in the og:video meta (different host, path shape, or escaping), or the post is an embed/crosspost whose og:video advertises HLS but the v.redd.it pattern does not appear in the page HTML.

Common situations: Reddit markup changes after the regexes were written; audio-less HLS posts where the og:video content is generated by JS and differs in the server-rendered HTML lux fetches.

Related errors


AI-assisted analysis of iawia002/lux@dd00f6d258 (2026-08-15). Data as JSON: /api/errors/eef773062c91a12f. Report an issue: GitHub.