{"record":{"id":"7165cc95c4c04bf2","repo":"infiniflow/ragflow","slug":"querit-name-must-be-an-array-of-strings","errorCode":null,"errorMessage":"Querit {name} must be an array of strings.","messagePattern":"Querit (.+?) must be an array of strings\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/tools/querit.py","lineNumber":420,"sourceCode":"    country_include: Any,\n    language_include: Any,\n) -> None:\n    if type(count) is not int or count < 1:\n        raise ValueError(\"Querit count must be an integer greater than or equal to 1.\")\n    if chunks_per_doc is not None and (type(chunks_per_doc) is not int or not 1 <= chunks_per_doc <= 3):\n        raise ValueError(\"Querit chunks_per_doc must be an integer from 1 to 3.\")\n    if type(time_range) is not str:\n        raise ValueError(\"Querit time_range must be a string.\")\n    if time_range and not TIME_RANGE_PATTERN.fullmatch(time_range):\n        raise ValueError(\"Querit time_range must use dN, wN, mN, yN, or YYYY-MM-DDtoYYYY-MM-DD.\")\n    for name, value in (\n        (\"site_include\", site_include),\n        (\"site_exclude\", site_exclude),\n        (\"country_include\", country_include),\n        (\"language_include\", language_include),\n    ):\n        if not isinstance(value, list) or any(not isinstance(item, str) for item in value):\n            raise ValueError(f\"Querit {name} must be an array of strings.\")\n\n\ndef _safe_error_message(error: Exception, api_key: str) -> str:\n    message = str(error) or error.__class__.__name__\n    return message.replace(api_key, \"[REDACTED]\") if api_key else message\n\n\ndef _querit_text(value: Any) -> str:\n    return \"\" if value is None else str(value)\n","sourceCodeStart":402,"sourceCodeEnd":430,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/tools/querit.py#L402-L430","documentation":"In _validate_search_inputs (agent/tools/querit.py:419-420), each of site_include, site_exclude, country_include, language_include must be a Python list whose every element is a str. The check is strict: None fails isinstance(None, list), so the parameters must be actual arrays even when empty. The f-string interpolates the offending parameter name into the message.","triggerScenarios":"Passing null/None instead of [] for any of the four filter parameters; passing a single string like 'wikipedia.org' instead of ['wikipedia.org']; passing a list containing numbers, booleans, dicts, or nested lists; JSON tool arguments where the field is an object instead of an array.","commonSituations":"LLM tool-calls emit a bare string for a one-element filter; a workflow upstream component outputs a scalar into a field the canvas expects as an array; JSON config written by hand uses null for 'no filter'.","solutions":["Always use JSON arrays of strings for these four fields, e.g. \"site_include\": [\"wikipedia.org\"], and [] when you want no filtering.","Never pass null/None - the validator rejects it; use an empty list instead.","If the value comes from another component's output, wrap or coerce it: list of strings before it reaches Querit.","Check every element's type - one non-string element (e.g. a number) fails the whole array."],"exampleFix":"// before\n\"site_include\": null,\n\"country_include\": \"us\"\n\n// after\n\"site_include\": [],\n\"country_include\": [\"us\"]","handlingStrategy":"type-guard","validationCode":"def normalize_str_array(v):\n    if v is None:\n        return []\n    if isinstance(v, str):\n        return [v]\n    if isinstance(v, list):\n        return [str(x) for x in v]\n    raise TypeError(f\"expected list of strings, got {type(v).__name__}\")\n\nsite_include = normalize_str_array(site_include)","typeGuard":"def is_str_array(value) -> bool:\n    return isinstance(value, list) and all(isinstance(item, str) for item in value)","tryCatchPattern":"try:\n    querit.run(site_include=si)\nexcept ValueError as e:\n    if \"array of strings\" in str(e):\n        querit.run(site_include=[])","preventionTips":["Never pass null for the four filter fields - use [].","Coerce upstream component outputs through a list-of-strings normalizer before they reach Querit.","Validate JSON tool-call arguments with a schema (items: {type: string}) when an LLM fills them."],"tags":["validation","agent","querit","type-error","arrays"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}