{"record":{"id":"2f96c7349e0224f4","repo":"infiniflow/ragflow","slug":"querit-urls-must-contain-between-1-and-10-non-empt","errorCode":null,"errorMessage":"Querit urls must contain between 1 and 10 non-empty strings.","messagePattern":"Querit urls must contain between 1 and 10 non-empty strings\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/tools/querit.py","lineNumber":374,"sourceCode":"\ndef _build_contents_payload(urls: list[str], format: str, crawl_timeout: int, extras_meta: bool) -> dict[str, Any]:\n    return {\n        \"urls\": urls,\n        \"format\": format,\n        \"crawlTimeout\": crawl_timeout,\n        \"extrasMeta\": extras_meta,\n    }\n\n\ndef _normalize_contents_urls(urls: Any) -> Any:\n    if isinstance(urls, str):\n        return [url.strip() for url in urls.split(\",\") if url.strip()]\n    return urls\n\n\ndef _validate_contents_inputs(urls: Any, format: Any, crawl_timeout: Any, extras_meta: Any) -> None:\n    if not isinstance(urls, list) or not 1 <= len(urls) <= 10 or any(not isinstance(url, str) or not url.strip() for url in urls):\n        raise ValueError(\"Querit urls must contain between 1 and 10 non-empty strings.\")\n    for url in urls:\n        parsed = urlparse(url)\n        if parsed.scheme not in {\"http\", \"https\"} or not parsed.netloc:\n            raise ValueError(\"Querit urls must be absolute HTTP or HTTPS URLs.\")\n    if format not in QUERIT_CONTENT_FORMATS:\n        raise ValueError(\"Querit format must be text, markdown, or html.\")\n    if type(crawl_timeout) is not int or not 1 <= crawl_timeout <= 60:\n        raise ValueError(\"Querit crawl_timeout must be an integer from 1 to 60.\")\n    if type(extras_meta) is not bool:\n        raise ValueError(\"Querit extras_meta must be a boolean.\")\n\n\ndef _validate_contents_response(response_data: Any) -> None:\n    if not isinstance(response_data, dict):\n        raise TypeError(\"Querit API response must be a JSON object.\")\n    if \"results\" in response_data and not isinstance(response_data[\"results\"], list):\n        raise TypeError(\"Querit API response field results must be an array.\")\n    if \"statuses\" in response_data and not isinstance(response_data[\"statuses\"], list):","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/tools/querit.py#L356-L392","documentation":"ValueError from _validate_contents_inputs() in the Querit contents tool. The 'urls' input must be a list of 1 to 10 non-empty strings after normalization (_normalize_contents_urls splits a comma-separated string). It fails when urls is not a list, is empty or has more than 10 entries, or any entry is a blank/non-string.","triggerScenarios":"Invoking Querit contents with urls=[], urls containing 11 entries, an entry of '' or whitespace, urls passed as a raw number/None from workflow parameter binding, or a comma string like ', ,' that normalizes to an empty list.","commonSituations":"LLM-generated component inputs that emit an empty array when unsure; upstream node producing null urls; users pasting newline-separated URLs where the input form produced a single string without commas; exceeding the 10-URL batch cap.","solutions":["Pass urls as a comma-separated string or a JSON array with 1-10 entries, each an absolute non-empty URL.","Trim whitespace and drop empty elements before invoking (a CSV input 'a.com, ,b.com' becomes ['a.com','b.com'] only if you strip blanks yourself first).","Split batches larger than 10 into multiple calls.","If urls comes from an upstream component, add a non-empty guard before wiring it to Querit contents."],"exampleFix":"# before\nurls = [\"https://a.com\", \"\", \" \"]  # 2 blank entries -> ValueError\n\n# after\nurls = [u.strip() for u in url_string.split(\",\") if u.strip()][:10]","handlingStrategy":"validation","validationCode":"from typing import Any\ndef normalize_querit_urls(urls: Any) -> list[str]:\n    if isinstance(urls, str):\n        urls = [u.strip() for u in urls.split(\",\") if u.strip()]\n    assert isinstance(urls, list) and 1 <= len(urls) <= 10, \"need 1-10 urls\"\n    return [u for u in urls if isinstance(u, str) and u.strip()]","typeGuard":"def is_valid_querit_urls(v: Any) -> bool:\n    return (\n        isinstance(v, list)\n        and 1 <= len(v) <= 10\n        and all(isinstance(u, str) and u.strip() for u in v)\n    )","tryCatchPattern":"try:\n    querit_contents._invoke(urls=urls)\nexcept ValueError as e:\n    if \"between 1 and 10\" in str(e):\n        urls = normalize_querit_urls(urls)\n        querit_contents._invoke(urls=urls)\n    raise","preventionTips":["Batch URLs in chunks of 10 at the caller.","Strip blanks and dedupe before passing the list.","Guard upstream component outputs for None before wiring to urls."],"tags":["validation","input","querit","urls"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}