{"record":{"id":"370794ed3b96efab","repo":"infiniflow/ragflow","slug":"new-name-can-only-be-used-with-a-single-file","errorCode":null,"errorMessage":"new_name can only be used with a single file","messagePattern":"new_name can only be used with a single file","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"api/utils/validation_utils.py","lineNumber":1097,"sourceCode":"    \"\"\"Request model for deleting files.\"\"\"\n\n    ids: Annotated[list[str], Field(min_length=1)]\n\n\nclass MoveFileReq(Base):\n    \"\"\"Request model for moving or renaming files.\"\"\"\n\n    src_file_ids: Annotated[list[str], Field(min_length=1)]\n    dest_file_id: Annotated[str | None, Field(default=None)]\n    new_name: Annotated[str | None, StringConstraints(strip_whitespace=True, min_length=1, max_length=255), Field(default=None)]\n\n    @model_validator(mode=\"after\")\n    def check_operation(self):\n        \"\"\"Require either a destination folder or a new file name.\"\"\"\n        if not self.dest_file_id and not self.new_name:\n            raise ValueError(\"At least one of dest_file_id or new_name must be provided\")\n        if self.new_name and len(self.src_file_ids) > 1:\n            raise ValueError(\"new_name can only be used with a single file\")\n        return self\n\n\nclass ListFileReq(BaseModel):\n    \"\"\"Request model for listing files.\"\"\"\n\n    model_config = ConfigDict(extra=\"forbid\")\n\n    parent_id: Annotated[str | None, Field(default=None)]\n    keywords: Annotated[str, Field(default=\"\")]\n    page: Annotated[int, Field(default=1, ge=1)]\n    page_size: Annotated[int, Field(default=15, ge=1)]\n    orderby: Annotated[str, Field(default=\"create_time\")]\n    desc: Annotated[bool, Field(default=True)]\n\n    @field_validator(\"page_size\")\n    @classmethod\n    def validate_page_size(cls, v: int) -> int:","sourceCodeStart":1079,"sourceCodeEnd":1115,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/utils/validation_utils.py#L1079-L1115","documentation":"ValueError from MoveFileReq.check_operation (api/utils/validation_utils.py:1097). Renaming via new_name is inherently single-object: giving several files one new name is meaningless, so when src_file_ids has more than one entry and new_name is set, Pydantic rejects the request. Move-many and rename-one must be separate calls.","triggerScenarios":"POST to the move/rename endpoint with len(src_file_ids) > 1 AND a non-null new_name in the same payload.","commonSituations":"UI letting users multi-select then type a name; generic client code that always fills both fields; merging a 'rename' form state into a bulk-move request.","solutions":["Drop new_name when moving multiple files (send only src_file_ids + dest_file_id).","Issue one request per file when renaming: src_file_ids=[one_id] with new_name.","Disable the rename field in the UI whenever more than one file is selected."],"exampleFix":"// before\n{\"src_file_ids\": [\"f1\", \"f2\"], \"dest_file_id\": \"d1\", \"new_name\": \"renamed\"}\n// after\n{\"src_file_ids\": [\"f1\", \"f2\"], \"dest_file_id\": \"d1\"}","handlingStrategy":"validation","validationCode":"if len(src_file_ids) > 1:\n    payload.pop(\"new_name\", None)\nif payload.get(\"new_name\") and len(src_file_ids) > 1:\n    raise AssertionError(\"unreachable: new_name must be dropped for multi-file moves\")","typeGuard":"def is_single_file_rename(src: list[str], new_name: str | None) -> bool:\n    return new_name is None or len(src) == 1","tryCatchPattern":"try:\n    req = MoveFileReq(**payload)\nexcept ValidationError as e:\n    if \"single file\" in str(e):\n        payload.pop(\"new_name\")\n        req = MoveFileReq(**payload)\n    else:\n        raise","preventionTips":["Model move and rename as separate UI actions and separate request builders.","Never populate both new_name and multiple src_file_ids.","Loop per-file for bulk renames."],"tags":["validation","pydantic","file-management","move-rename"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}