ZhuLinsen/daily_stock_analysis · warning · IntelligenceServiceError
unsupported feed format; expected RSS or Atom
Error message
unsupported feed format; expected RSS or Atom
What it means
IntelligenceServiceError('unsupported feed format; expected RSS or Atom') is raised by _parse_feed when the body parses as valid XML but the root element (namespace-stripped, lowercased) is neither 'rss' nor 'feed'. The service deliberately supports only RSS (<rss><channel><item>) and Atom (<feed><entry>) shapes.
Source
Thrown at src/services/intelligence_service.py:608
ip = ipaddress.ip_address(info[4][0])
except (IndexError, TypeError, ValueError):
continue
if IntelligenceService._is_blocked_ip(ip):
raise IntelligenceServiceError("source url must not target private or local network addresses")
def _parse_feed(self, content: bytes, *, source_name: str, limit: int) -> List[FeedEntry]:
try:
root = ET.fromstring(content)
except ET.ParseError as exc:
raise IntelligenceServiceError(f"invalid RSS/Atom feed: {exc}") from exc
tag = self._strip_ns(root.tag).lower()
if tag == "rss":
nodes = root.findall("./channel/item")
return [entry for entry in (self._parse_rss_item(node, source_name) for node in nodes[:limit]) if entry]
if tag == "feed":
nodes = root.findall("./{*}entry") or root.findall("./entry")
return [entry for entry in (self._parse_atom_entry(node, source_name) for node in nodes[:limit]) if entry]
raise IntelligenceServiceError("unsupported feed format; expected RSS or Atom")
def _parse_newsnow_payload(self, payload: Any, *, source_name: str, limit: int) -> List[FeedEntry]:
if not isinstance(payload, dict):
raise IntelligenceServiceError("invalid NewsNow response: expected object")
items = payload.get("items")
if not isinstance(items, list):
raise IntelligenceServiceError("invalid NewsNow response: missing items")
entries = []
for item in items[:limit]:
if not isinstance(item, dict):
continue
extra = item.get("extra") if isinstance(item.get("extra"), dict) else {}
published_raw = item.get("pubDate") or extra.get("date")
entries.append(self._build_entry(
str(item.get("title") or ""),
str(extra.get("info") or extra.get("hover") or ""),
str(item.get("url") or item.get("mobileUrl") or ""),
source_name,View on GitHub (pinned to 5159bd72e8)
Solutions
- Inspect the root element: curl -sL <url> | head -c 200 and confirm it starts with <rss or <feed
- If it is RSS 1.0/RDF, find the provider's RSS 2.0 or Atom endpoint instead
- If the source only emits JSON, use the NewsNow/JSON source type this service already supports rather than the RSS path
- Update the source entry in configuration to the correct feed URL
Example fix
# before: sitemap mistakenly configured as a feed url = "https://example.com/sitemap.xml" # after: real Atom feed url = "https://example.com/feeds/atom.xml"
Defensive patterns
Strategy: validation
Validate before calling
import xml.etree.ElementTree as ET
def root_is_rss_or_atom(content: bytes) -> bool:
try:
tag = ET.fromstring(content).tag.split('}')[-1].lower()
except ET.ParseError:
return False
return tag in {"rss", "feed"} Try / catch
try:
entries = svc._parse_feed(content, source_name=src, limit=20)
except IntelligenceServiceError as exc:
if "unsupported feed format" in str(exc):
logger.warning("%s is not RSS/Atom; find the correct feed URL", src) Prevention
- Verify the root element is <rss> or <feed> when registering a new source
- Do not reuse sitemap/OPML/RDF URLs as feed sources
- Use JSON/NewsNow source type for JSON-only providers
When it happens
Trigger: Feeding a generic XML document (e.g. RDF/Sitemap.xml, OPML, an RSS 1.0 RDF variant whose root is <rdf:RDF>), a JSON payload misconfigured with a feed-type source, or any well-formed XML whose root tag is not rss/feed.
Common situations: Configuring a sitemap or news-sitemap URL as a feed source, an RSS 1.0 (RDF) endpoint, a source that switched its feed technology (e.g. to JSON-only), or a copy-paste mistake putting an article URL instead of the feed URL.
Related errors
- invalid RSS/Atom feed: {exc}
- invalid NewsNow response: expected object
- [AlphaVantage] API key not configured
- {market_label} {stock_code} 获取失败: 暂无可用数据源
- 无法确定 ETF {stock_code} 的 Eastmoney 市场前缀
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/44f26b452d76ab5b.
Report an issue: GitHub.