block matching the regex. The LD-JSON payload is how the extractor finds ContentURL, so without it nothing can be extracted. The page downloaded fine but its structure is not what the extractor expects.","about":"iawia002/lux — Could not read page data","url":"https://errors.standardbeagle.com/iawia002/lux/could-not-read-page-data/","proficiencyLevel":"Expert","keywords":"odysee, html-parsing, regex, site-layout-change"},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What causes \"Could not read page data\" in iawia002/lux?","acceptedAnswer":{"@type":"Answer","text":"Dump the response body (err is nil, so re-fetch the URL manually with the same headers) and inspect what page Odysee actually served"}}]}]}

iawia002/lux · error

Could not read page data

Error message

Could not read page data

What it means

Thrown by the Odysee extractor when the fetched claim page's bytes do not contain a <script type="application/ld+json">...</script> block matching the regex. The LD-JSON payload is how the extractor finds ContentURL, so without it nothing can be extracted. The page downloaded fine but its structure is not what the extractor expects.

Source

Thrown at extractors/odysee/odysee.go:61

	switch res.Header.Get("Content-Encoding") {
	case "gzip":
		reader, _ = gzip.NewReader(res.Body)
	case "deflate":
		reader = flate.NewReader(res.Body)
	default:
		reader = res.Body
	}
	defer reader.Close() // nolint

	b, err := io.ReadAll(reader)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	regScript := regexp.MustCompile(`(?im)\<script type="application\/ld\+json"\>([\s\S]*)[\n?]<\/script>`)
	matchPayload := regScript.FindSubmatch(b)
	if len(matchPayload) < 2 {
		return nil, errors.New("Could not read page data")
	}

	var resData odyseePayload
	if err := json.Unmarshal(matchPayload[1], &resData); err != nil {
		return nil, errors.WithStack(err)
	}

	streams := make(map[string]*extractors.Stream, 1)
	size, err := request.Size(resData.ContentURL, u)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	streams["Default"] = &extractors.Stream{
		Parts: []*extractors.Part{
			{
				URL:  resData.ContentURL,
				Size: size,

View on GitHub (pinned to dd00f6d258)

Solutions

  1. Dump the response body (err is nil, so re-fetch the URL manually with the same headers) and inspect what page Odysee actually served
  2. Confirm the claim URL opens in a browser and shows a video with an ld+json block in view-source
  3. If the markup changed, update regScript in extractors/odysee/odysee.go to match the current script tag layout
  4. If a challenge page is served, retry from a residential IP or with browser-like headers

Example fix

// before
matchPayload := regScript.FindSubmatch(b)
if len(matchPayload) < 2 {
    return nil, errors.New("Could not read page data")
}

// after (diagnose what was actually served before failing)
matchPayload := regScript.FindSubmatch(b)
if len(matchPayload) < 2 {
    return nil, fmt.Errorf("could not read page data: no ld+json block in %d bytes (served title: %q)",
        len(b), utils.MatchOneOf(string(b), `<title>(.*?)</title>`))
}
Defensive patterns

Strategy: try-catch

Try / catch

_, err := odysee.Extract(url, opts)
if err != nil {
    if strings.Contains(err.Error(), "Could not read page data") {
        // page served without ld+json: markup change or bot wall; log and skip
    }
    return err
}

Prevention

When it happens

Trigger: Calling Extract on an Odysee claim URL where the server returns an error page, an anti-bot/consent interstitial, or a redesigned page whose ld+json script tag no longer matches `(?im)<script type="application\/ld+json">([\s\S]*)[\n?]</script>`. Also triggered by a mistyped claim name that yields a non-content page.

Common situations: Odysee front-end markup changed after the regex was written, datacenter IP blocked and served a challenge page, or the URL points at a channel/livestream rather than a claim with a playable content URL.

Related errors


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