infiniflow/ragflow · error · ValueError

Querit extras_meta must be a boolean.

Error message

Querit extras_meta must be a boolean.

What it means

ValueError from _validate_contents_inputs(): the extras_meta flag of the Querit contents tool must be a strict boolean. The check uses type(extras_meta) is not bool, so 1/0, 'true'/'false' strings, and None all fail even though they are truthy/falsy or JSON-ish.

Source

Thrown at agent/tools/querit.py:384

def _normalize_contents_urls(urls: Any) -> Any:
    if isinstance(urls, str):
        return [url.strip() for url in urls.split(",") if url.strip()]
    return urls


def _validate_contents_inputs(urls: Any, format: Any, crawl_timeout: Any, extras_meta: Any) -> None:
    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):
        raise ValueError("Querit urls must contain between 1 and 10 non-empty strings.")
    for url in urls:
        parsed = urlparse(url)
        if parsed.scheme not in {"http", "https"} or not parsed.netloc:
            raise ValueError("Querit urls must be absolute HTTP or HTTPS URLs.")
    if format not in QUERIT_CONTENT_FORMATS:
        raise ValueError("Querit format must be text, markdown, or html.")
    if type(crawl_timeout) is not int or not 1 <= crawl_timeout <= 60:
        raise ValueError("Querit crawl_timeout must be an integer from 1 to 60.")
    if type(extras_meta) is not bool:
        raise ValueError("Querit extras_meta must be a boolean.")


def _validate_contents_response(response_data: Any) -> None:
    if not isinstance(response_data, dict):
        raise TypeError("Querit API response must be a JSON object.")
    if "results" in response_data and not isinstance(response_data["results"], list):
        raise TypeError("Querit API response field results must be an array.")
    if "statuses" in response_data and not isinstance(response_data["statuses"], list):
        raise TypeError("Querit API response field statuses must be an array.")


def _validate_search_inputs(
    count: Any,
    chunks_per_doc: Any,
    time_range: Any,
    site_include: Any,
    site_exclude: Any,
    country_include: Any,

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Pass a real boolean: extras_meta=True or extras_meta=False.
  2. Coerce strings in your caller: value in {"true", "1", "yes"} (case-insensitive) maps to True.
  3. Never rely on truthiness — 1 and 0 are explicitly rejected by the strict type check.
  4. Give the field an explicit default of False when building component params programmatically.

Example fix

# before
extras_meta = "true"  # str -> ValueError

# after
extras_meta = str(value).strip().lower() in {"true", "1", "yes"}
Defensive patterns

Strategy: type-guard

Validate before calling

def to_bool_strict(v) -> bool:
    if isinstance(v, bool):
        return v
    if isinstance(v, str):
        return v.strip().lower() in {"true", "1", "yes"}
    raise ValueError(f"cannot coerce {v!r} to bool")

Type guard

def is_strict_bool(v) -> bool:
    return type(v) is bool

Try / catch

try:
    querit_contents._invoke(urls=urls, extras_meta=flag)
except ValueError as e:
    if "extras_meta" in str(e):
        flag = to_bool_strict(flag); querit_contents._invoke(urls=urls, extras_meta=flag)
    raise

Prevention

When it happens

Trigger: extras_meta=1, extras_meta='true' (form/env string), extras_meta=None (unset optional field), or extras_meta=[True] coming from loosely-typed workflow parameter binding.

Common situations: YAML/ENV-configured workflows where booleans arrive as strings; LLM tool-call JSON with "true" quoted; Python callers passing flags as 0/1 out of C-style habit.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/4cc3abb852e80187. Report an issue: GitHub.