Tencent/WeKnora · error

render article html: %w

Error message

render article html: %w

What it means

Returned when article.RenderHTML(&buf) fails to serialize the extracted readability article node into HTML. This is rare: it occurs when the cleaned DOM cannot be written to the output writer — typically an underlying write error on the bytes.Buffer (which practically never fails) or serialization of a malformed node tree produced by the parser.

Source

Thrown at internal/datasource/connector/rss/client.go:120

// caller can fall back to feed-provided content.
func (c *client) extractArticle(ctx context.Context, articleURL string) (contentHTML, title string, err error) {
	body, err := c.fetch(ctx, articleURL, maxArticleSize, false)
	if err != nil {
		return "", "", err
	}

	pageURL, _ := url.Parse(articleURL)
	article, err := readability.FromReader(bytes.NewReader(body), pageURL)
	if err != nil {
		return "", "", fmt.Errorf("readability parse: %w", err)
	}
	if article.Node == nil {
		return "", "", fmt.Errorf("no readable content extracted")
	}

	var buf bytes.Buffer
	if err := article.RenderHTML(&buf); err != nil {
		return "", "", fmt.Errorf("render article html: %w", err)
	}
	return buf.String(), article.Title(), nil
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Upgrade codeberg.org/readeck/go-readability/v2 to the latest version — rendering bugs are fixed upstream regularly.
  2. Treat this as per-item failure: fall back to feed-provided content in resolveItem and continue indexing other items.
  3. If reproducible on a specific page, capture the HTML and file a minimal reproduction upstream.
  4. Verify memory headroom on the host if the failure correlates with very large articles.

Example fix

// before
contentHTML, title, err := cli.extractArticle(ctx, item.Link)
if err != nil {
    log.Fatal(err) // aborts whole walk
}
// after
contentHTML, title, err := cli.extractArticle(ctx, item.Link)
if err != nil {
    log.Warnf("article extraction failed (%v), using feed content", err)
    contentHTML, title = item.Content, item.Title
}
Defensive patterns

Strategy: fallback

Try / catch

contentHTML, title, err := cli.extractArticle(ctx, item.Link)
if err != nil {
    log.Warnf("render failed for %s: %v; using feed content", item.Link, err)
    contentHTML, title = item.Content, item.Title
}

Prevention

When it happens

Trigger: A pathological page produces a readability node tree that the renderer cannot serialize; a bug or incompatibility in the go-readability v2 library version; out-of-memory conditions while growing the output buffer for a pathological article.

Common situations: Pages with deeply malformed or adversarial markup that survive parsing but break rendering; running an older go-readability build with a known rendering bug; extremely large extracted articles causing allocation failures.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/0595033bfe332994. Report an issue: GitHub.