{"record":{"id":"e78f0bd420ecd4a4","repo":"iflytek/astron-agent","slug":"either-fileurl-or-file-must-be-provided","errorCode":null,"errorMessage":"Either fileUrl or file must be provided","messagePattern":"Either fileUrl or file must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"core/knowledge/service/impl/ragflow_strategy.py","lineNumber":193,"sourceCode":"        results = RagflowUtils.convert_ragflow_query_response(\n            ragflow_response, threshold\n        )\n        if effective_top_k and effective_top_k > 0:\n            results = results[:effective_top_k]\n\n        logger.info(\"Query completed, returning %d results\", len(results))\n        return {\"query\": query, \"count\": len(results), \"results\": results}\n\n    def _empty_query_result(self, query: str) -> Dict[str, Any]:\n        \"\"\"Unified empty-result format for query paths.\"\"\"\n        return {\"query\": query, \"count\": 0, \"results\": []}\n\n    def _validate_split_parameters(\n        self, fileUrl: Optional[str], file: Optional[Any]\n    ) -> None:\n        \"\"\"Validate split method parameters.\"\"\"\n        if not fileUrl and not file:\n            raise ValueError(\"Either fileUrl or file must be provided\")\n        if fileUrl and file:\n            raise ValueError(\"Cannot provide both fileUrl and file parameters\")\n\n    def _parse_form_data_parameters(\n        self,\n        lengthRange: Optional[List[int]],\n        separator: Optional[List[str]],\n        cutOff: Optional[List[str]],\n    ) -> tuple[Optional[List[int]], Optional[List[str]], Optional[List[str]]]:\n        \"\"\"Parse form-data parameters from JSON strings.\"\"\"\n        parsed_length_range = lengthRange\n        parsed_separator = separator\n        parsed_cut_off = cutOff\n\n        if isinstance(lengthRange, str):\n            try:\n                parsed_length_range = json.loads(lengthRange) if lengthRange else None\n            except (json.JSONDecodeError, TypeError):","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/knowledge/service/impl/ragflow_strategy.py#L175-L211","documentation":"Raised by _validate_split_parameters (core/knowledge/service/impl/ragflow_strategy.py:193) when split() is invoked with neither fileUrl nor a file object in kwargs. The RAGFlow split strategy requires exactly one file input source — either a URL/path or an uploaded file — to upload and parse into chunks.","triggerScenarios":"Calling strategy.split() with no arguments, or with fileUrl=None and no 'file' key in kwargs; also when the caller passes an empty string for fileUrl (falsy) and no file.","commonSituations":"Frontend form submitted without attaching a file or filling the fileUrl field; API layer dropped the multipart file during request forwarding; caller intended re-slicing with only document_id but forgot the new file source; a code path constructs split kwargs dynamically and misses the input key.","solutions":["Pass exactly one input: either fileUrl='https://...' (URL or accessible path) or file=<uploaded file object> via kwargs.","If using the HTTP API, ensure the request is multipart/form-data with a populated 'file' part.","Check the calling code that assembles split() kwargs — the input key may be named differently (e.g. 'file_url') and silently dropped by **kwargs.","Validate inputs client-side before invoking split so the user gets an actionable message."],"exampleFix":"// before\nchunks = await strategy.split()  # neither source provided\n\n// after\nchunks = await strategy.split(fileUrl=\"https://example.com/doc.pdf\")\n// or\nchunks = await strategy.split(**{\"file\": uploaded_file})","handlingStrategy":"validation","validationCode":"def ensure_split_input(fileUrl, file):\n    if not fileUrl and not file:\n        raise ValueError(\"split requires fileUrl or file\")\n    if fileUrl and file:\n        raise ValueError(\"provide only one of fileUrl and file\")","typeGuard":"def has_file_input(fileUrl, file) -> bool:\n    return bool(file) or isinstance(fileUrl, str) and bool(fileUrl.strip())","tryCatchPattern":"try:\n    chunks = await strategy.split(**split_kwargs)\nexcept ValueError as e:\n    return {\"error\": \"invalid_input\", \"detail\": str(e), \"hint\": \"attach a file or set fileUrl\"}","preventionTips":["Validate request payloads in the API layer before reaching the strategy.","For multipart forms, assert the file part is present and non-empty.","Make UIs require exactly one of upload vs URL.","Watch for kwargs key-name mismatches that silently drop the file input."],"tags":["validation","missing-argument","ragflow","split"],"backgroundTag":"missing-required-argument","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}