Tencent/WeKnora · error
parse feed %s: %w
Error message
parse feed %s: %w
What it means
Returned by Connector.Validate when the feed bytes were fetched successfully but gofeed's parser.Parse could not recognize them as RSS, Atom, or JSON Feed. gofeed sniffs the document structure; a 200 response that is an HTML page (login page, soft-404, bot-challenge, or homepage) fails parsing even though the fetch succeeded.
Source
Thrown at internal/datasource/connector/rss/connector.go:46
func (c *Connector) Type() string { return types.ConnectorTypeRSS }
// Validate verifies that every configured feed URL is reachable and parses as
// a valid feed.
func (c *Connector) Validate(ctx context.Context, config *types.DataSourceConfig) error {
cfg, err := parseConfig(config)
if err != nil {
return err
}
cli := newClient(cfg.parseHeaders())
parser := gofeed.NewParser()
for _, feedURL := range cfg.feedURLList() {
data, err := cli.fetchFeed(ctx, feedURL)
if err != nil {
return fmt.Errorf("fetch feed %s: %w", feedURL, err)
}
if _, err := parser.Parse(bytes.NewReader(data)); err != nil {
return fmt.Errorf("parse feed %s: %w", feedURL, err)
}
}
return nil
}
// ResolveResourceAncestors has nothing to do: feeds are a flat list with no
// nesting, so a selection has no ancestors to reveal.
func (c *Connector) ResolveResourceAncestors(
ctx context.Context, config *types.DataSourceConfig, resourceIDs []string,
) ([]string, error) {
return []string{}, nil
}
// ListResources returns one resource per configured feed URL. The feed is
// fetched so the resource can carry its real title; a feed that fails to fetch
// still appears (named by URL) with an error note, so the user can deselect it
// instead of the whole listing failing.
func (c *Connector) ListResources(View on GitHub (pinned to 988cbb0330)
Solutions
- Confirm the URL returns actual RSS/Atom: open it in a browser or validate the response with an XML parser; use the site's real feed path (commonly /feed, /rss.xml, /atom.xml).
- Validate the feed XML with xmllint or the W3C feed validator to find the exact malformation, then fix it at the source.
- If a bot-protection page is served with status 200, request a rule exemption for the connector's User-Agent or fetch via a cache/proxy.
- Check you are not pointing at sitemap.xml or an HTML page — gofeed only parses RSS, Atom, and JSON Feed.
Example fix
// before feeds: ["https://blog.example"] // after feeds: ["https://blog.example/feed.xml"]
Defensive patterns
Strategy: validation
Validate before calling
func sniffIsFeed(body []byte) bool {
s := strings.TrimSpace(string(body[:min(len(body), 512)]))
lower := strings.ToLower(s)
return strings.HasPrefix(lower, "<?xml") &&
(strings.Contains(lower, "<rss") || strings.Contains(lower, "<feed")) ||
strings.HasPrefix(lower, "{") && strings.Contains(lower, "\"version\"")
} Try / catch
err := connector.Validate(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "parse feed") {
feedURL := extractFeedURL(err.Error())
return fmt.Errorf("%s did not return RSS/Atom/JSON feed content; check the URL points at the feed, not the site", feedURL)
} Prevention
- Verify the URL serves RSS/Atom XML (or JSON Feed) before configuring it — prefer /feed, /rss.xml, /atom.xml over the site root.
- Run feeds through the W3C feed validator or xmllint when a generator is suspected.
- Watch for bot-protection pages served with status 200; exempt the connector's User-Agent if needed.
- Keep feed URLs from trusted sources; hand-edited feeds often have malformed XML.
When it happens
Trigger: The URL returns HTML instead of a feed (soft-404s served with status 200, bot-protection interstitials, a homepage URL pasted instead of the feed URL); the feed is malformed XML with encoding errors or truncated tags; the document is a format gofeed doesn't support (e.g. RDF with unusual extensions, or a sitemap.xml mistaken for a feed).
Common situations: Users paste the site homepage rather than /feed or /rss.xml; feeds behind Cloudflare serving a challenge page with status 200; hand-edited or generator-broken feeds with invalid XML; WordPress pretty-permalink changes breaking the feed URL.
Related errors
- readability parse: %w
- fetch feed %s: %w
- ErrInvalidCredentials
- invalid task ID format: %s
- invite code has expired
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/9dfef34b741b3d7d.
Report an issue: GitHub.