{"record":{"id":"2fe3ffdfafcee324","repo":"iflytek/astron-agent","slug":"ragflow-ext-is-only-allowed-when-ragtype-ragflow-rag-got","errorCode":null,"errorMessage":"ragflow_ext is only allowed when ragType='Ragflow-RAG', got ragType='{self.ragType.value}'","messagePattern":"ragflow_ext is only allowed when ragType='Ragflow-RAG', got ragType='(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"core/knowledge/domain/entity/chunk_dto.py","lineNumber":296,"sourceCode":"            \"send the raw query (useful for keyword / highlight matching).\"\n        ),\n    )\n    match: QueryMatch = Field(..., description=\"Matching conditions\")\n    ragType: RAGType = Field(..., description=\"RAG type\")\n    history: List[Dict[str, Any]] = Field(default_factory=list)\n    ragflow_ext: Optional[RagflowQueryExt] = Field(\n        default=None,\n        description=(\n            \"Optional RAGFlow-specific retrieval parameters. Requires \"\n            \"ragType=Ragflow-RAG; other RAG types return a validation \"\n            \"error. When ragflow_ext.top_k is set, it overrides topN.\"\n        ),\n    )\n\n    @model_validator(mode=\"after\")\n    def _ragflow_ext_scope_check(self) -> \"ChunkQueryReq\":\n        if self.ragflow_ext is not None and self.ragType != RAGType.RagFlow_RAG:\n            raise ValueError(\n                f\"ragflow_ext is only allowed when ragType='Ragflow-RAG', \"\n                f\"got ragType='{self.ragType.value}'\"\n            )\n        return self\n\n\nclass QueryDocReq(BaseModel):\n    \"\"\"\n    Document query request model\n\n    Attributes:\n        docId: Document ID, required\n        ragType: RAG type\n        group: Knowledge base group used by non-Ragflow strategies, optional\n        datasetId: RAGFlow dataset.id for direct routing, optional\n    \"\"\"\n\n    docId: str = Field(..., min_length=1, description=\"Required, minimum length 1\")","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/knowledge/domain/entity/chunk_dto.py#L278-L314","documentation":"ChunkQueryReq is a Pydantic model with an @model_validator(mode=\"after\") that rejects requests combining ragflow_ext (RAGFlow-specific retrieval parameters like top_k) with any ragType other than RAGType.RagFlow_RAG. The validator runs automatically after field validation whenever the model is constructed, so any code path that builds a ChunkQueryReq with a mismatched pair fails at instantiation with a ValueError surfaced by Pydantic as a ValidationError.","triggerScenarios":"Constructing ChunkQueryReq (directly or via an API payload) with ragflow_ext set to a non-None RagflowQueryExt while ragType is anything other than RAGType.RagFlow_RAG (e.g. SPARKDESK-RAG or AIUI-RAG).","commonSituations":"Clients reusing a request template built for RAGFlow against another RAG backend; a caller hardcoding ragflow_ext.top_k from older code; frontend sending extra RAGFlow fields unconditionally; configuration where ragType was changed but the extension block was left in place.","solutions":["Set ragType to RAGType.RagFlow_RAG if RAGFlow-specific retrieval is genuinely required.","Otherwise omit ragflow_ext (or set it to None) from the ChunkQueryReq payload.","In the caller, conditionally include ragflow_ext only when the backend is RagFlow, e.g. build kwargs based on the active RAG type.","In API client code, validate/strip ragflow_ext before sending when ragType is not Ragflow-RAG."],"exampleFix":"// before\nreq = ChunkQueryReq(query=\"q\", topN=3, match=m, ragType=RAGType.SPARKDESK_RAG, ragflow_ext=RagflowQueryExt(top_k=3))\n// after\nreq = ChunkQueryReq(query=\"q\", topN=3, match=m, ragType=RAGType.RagFlow_RAG, ragflow_ext=RagflowQueryExt(top_k=3))\n# or drop the ext:\nreq = ChunkQueryReq(query=\"q\", topN=3, match=m, ragType=RAGType.SPARKDESK_RAG)","handlingStrategy":"validation","validationCode":"def can_use_ragflow_ext(rag_type: RAGType, ragflow_ext) -> bool:\n    return ragflow_ext is None or rag_type == RAGType.RagFlow_RAG\n# call before constructing ChunkQueryReq","typeGuard":"def is_ragflow(rag_type: RAGType) -> bool:\n    return rag_type == RAGType.RagFlow_RAG","tryCatchPattern":"try:\n    req = ChunkQueryReq(**payload)\nexcept ValidationError as e:\n    logger.warning(\"Invalid chunk query request: %s\", e)\n    raise HTTPException(status_code=422, detail=str(e))","preventionTips":["Strip ragflow_ext from payloads unless the backend is RagFlow","Model the payload with a discriminated union keyed on ragType","Add a unit test for each ragType with/without ragflow_ext"],"tags":["pydantic","validation","rag"],"backgroundTag":"schema-validation-failed","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"}