BerriAI/litellm · error · ValueError
RSS feed missing element
Error message
RSS feed missing <channel> element
What it means
get_llm_provider() (litellm_core_utils/get_llm_provider_logic.py) opens with early validation: if the model argument is None it immediately raises ValueError('model parameter is required but was None. Please provide a valid model name.') before any provider detection runs. Its job is resolving 'azure/foo' or 'openrouter/bar' prefixes to a provider, and None makes that impossible.
Solutions
- Find where the model value originates (env var, config, function arg) and make it a required, validated string.
- For Router/proxy configs, ensure every model_list entry has litellm_params.model set to a valid name like 'azure/my-deployment'.
- Fail fast at config load: validate all model strings before entering request paths.
- Use a sentinel/default model explicitly instead of letting None propagate.
Example fix
# before
model = os.getenv("MODEL") # None when unset
litellm.completion(model=model, messages=msgs)
# after
model = os.environ["MODEL"] # KeyError at startup, not mid-request
litellm.completion(model=model, messages=msgs) Defensive patterns
Strategy: try-catch
Validate before calling
import xml.etree.ElementTree as ET
root = ET.fromstring(xml_text)
assert root.find("channel") is not None, "document is not an RSS 2.0 feed; refusing to parse"
posts = RssClient.parse_rss_to_posts(xml_text) Type guard
def is_rss2_feed(xml_text: str) -> bool:
try:
return ET.fromstring(xml_text).find("channel") is not None
except ET.ParseError:
return False Try / catch
try:
posts = RssClient.parse_rss_to_posts(xml_text)
except ValueError as e:
if "missing <channel>" in str(e):
log.warning("feed shape changed or was blocked; skipping blog posts")
posts = []
else:
raise Prevention
- Treat blog-post fetching as best-effort: catch ValueError and degrade to no posts.
- Check fetched content-type/root tag before parsing external documents.
- Allowlist the feed hostname on egress proxies; block pages parse as XML and trip this.
When it happens
Trigger: litellm.completion(model=None, ...) or Router/get_llm_provider calls where the model string never got set: template/env-driven config leaving it blank, a dict key mismatch (using 'model_name' vs 'model'), or a deployment entry whose model field is absent.
Common situations: Dynamic code building the model string that yields None (env var unset, lookup miss); LiteLLM Proxy model_list entries missing 'litellm_params.model'; refactors renaming the variable passed as model; optional model args defaulting to None.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Cisco AI Defense guardrail: invalid rule definition
- Event hook is not in the supported event hooks
- Event hook is not in the supported event hooks
- max_bytes_per_call must be >= 0 (0 disables the cap…
- api_base is required
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/8430eed166b0f799.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/litellm_core_utils/get_blog_posts.py:78
Fetch RSS XML from a remote URL.
Returns the raw XML text. Raises on network errors.
"""
response: Final = httpx.get(url, timeout=timeout)
response.raise_for_status()
return response.text
@staticmethod
def parse_rss_to_posts(xml_text: str, max_posts: int = 1) -> list[dict[str, str]]:
"""
Parse RSS XML and return a list of blog post dicts.
Extracts title, description, date (YYYY-MM-DD), and url from each <item>.
"""
root: Final = ET.fromstring(xml_text)
channel: Final = root.find("channel")
if channel is None:
raise ValueError("RSS feed missing <channel> element")
posts: Final[list[dict[str, str]]] = []
for item in channel.findall("item"):
if len(posts) >= max_posts:
break
title_el = item.find("title")
link_el = item.find("link")
desc_el = item.find("description")
pub_date_el = item.find("pubDate")
if title_el is None or link_el is None:
continue
# Parse RFC 2822 date to YYYY-MM-DD
date_str = ""
if pub_date_el is not None and pub_date_el.text:
try:View on GitHub (pinned to 77b7c6c40c)