iawia002/lux · error

url is null

Error message

url is null

What it means

utils.M3u8URLs refuses to run when handed an empty string: len(uri) == 0 returns 'url is null'. This is an argument-validation error — the function itself is fine, the caller passed an empty playlist URL. The real bug is upstream: whatever produced the m3u8 URL (an extractor's stream parsing) came back empty.

Source

Thrown at utils/utils.go:269

	// has no suffix
	contentType, err := request.ContentType(uri, uri)
	if err != nil {
		return "", "", err
	}
	return filename[0], strings.Split(contentType, "/")[1], nil
}

// Md5 md5 hash
func Md5(text string) string {
	sign := md5.New()
	sign.Write([]byte(text)) // nolint
	return fmt.Sprintf("%x", sign.Sum(nil))
}

// M3u8URLs get all urls from m3u8 url
func M3u8URLs(uri string) ([]string, error) {
	if len(uri) == 0 {
		return nil, errors.New("url is null")
	}

	html, err := request.Get(uri, "", nil)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	lines := strings.Split(html, "\n")
	var urls []string
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line != "" && !strings.HasPrefix(line, "#") {
			if strings.HasPrefix(line, "http") {
				urls = append(urls, line)
			} else {
				base, err := url.Parse(uri)
				if err != nil {
					continue
				}

View on GitHub (pinned to dd00f6d258)

Solutions

  1. Check the uri argument for emptiness at the call site before invoking M3u8URLs and fail with a message naming the upstream extraction step
  2. Trace back to where the m3u8 URL was produced and fix the extraction that returned ""
  3. Add a nil/empty guard on the regex capture that builds the playlist URL
  4. Write a unit test covering the empty-input path to lock in the behavior

Example fix

// before
urls, err := utils.M3u8URLs(playlistURL) // playlistURL may be ""
if err != nil { return err }

// after
if playlistURL == "" {
    return errors.New("stream extraction produced an empty m3u8 playlist URL")
}
urls, err := utils.M3u8URLs(playlistURL)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(playlistURL) == "" {
    return nil, errors.New("refusing to fetch m3u8: playlist URL is empty (upstream extraction failed)")
}
urls, err := utils.M3u8URLs(playlistURL)

Try / catch

urls, err := utils.M3u8URLs(playlistURL)
if err != nil {
    if strings.Contains(err.Error(), "url is null") {
        // argument bug on our side: find why playlistURL is empty, do not retry
        return fmt.Errorf("m3u8 extraction upstream produced empty URL for %s", pageURL)
    }
    return err
}

Prevention

When it happens

Trigger: An extractor resolves a stream to an m3u8 playlist, the resolution yields "" (regex miss upstream), and M3u8URLs is called with it anyway. Typical in HLS-based extractors after the host page changed shape.

Common situations: Site markup changes making the playlist-URL regex capture empty; nil-vs-empty confusion after a failed MatchOneOf; refactors that drop the assignment of the URL.


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