{"record":{"id":"44847144fd8f6423","repo":"infiniflow/ragflow","slug":"only-one-tree-template-in-a-group-may-enable-re-ch","errorCode":null,"errorMessage":"Only one tree template in a group may enable re-chunking.","messagePattern":"Only one tree template in a group may enable re-chunking\\.","errorType":"validation","errorClass":"GroupValidationError","httpStatus":null,"severity":"error","filePath":"api/db/services/compilation_template_group_service.py","lineNumber":71,"sourceCode":"    \"\"\"At most one tree-kind child in the group may enable re-chunking.\n\n    Re-chunking soft-deletes the doc's original chunks via\n    ``available_int=0`` and inserts merged replacements; running two\n    such templates would race on the same source chunks and produce\n    non-deterministic output. Per-tenant invariant is enforced\n    server-side here and mirrored client-side in\n    ``group-interface.ts``.\n    \"\"\"\n    rechunk_trees = 0\n    for t in templates:\n        if str((t or {}).get(\"kind\") or \"\").strip() != \"tree\":\n            continue\n        cfg = (t or {}).get(\"config\") or {}\n        raptor = (cfg or {}).get(\"raptor\") or {}\n        if bool(raptor.get(\"rechunk\")):\n            rechunk_trees += 1\n    if rechunk_trees > 1:\n        raise GroupValidationError(\"Only one tree template in a group may enable re-chunking.\")\n\n\nclass CompilationTemplateGroupService(CommonService):\n    model = CompilationTemplateGroup\n\n    @classmethod\n    def ensure_table(cls) -> None:\n        if not cls.model.table_exists():\n            cls.model.create_table(safe=True)\n\n    # ------------------------------------------------------------------\n    # Read paths\n    # ------------------------------------------------------------------\n\n    @classmethod\n    def _group_to_dict(cls, group: CompilationTemplateGroup, templates: list[CompilationTemplate]) -> dict:\n        from api.db.services.compilation_template_service import CompilationTemplateService\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/compilation_template_group_service.py#L53-L89","documentation":"Raised by GroupValidationError when saving a compilation template group whose tree templates include more than one with config.raptor.rechunk enabled. The service counts tree-kind templates with raptor.rechunk truthy and rejects the group if that count exceeds one, because re-chunking rebuilds the chunk tree and multiple re-chunking templates in one group would conflict.","triggerScenarios":"PUT/POST of a template group payload where two or more entries have kind=='tree' and config.raptor.rechunk set (e.g. {'raptor': {'rechunk': true}}) in their config objects. The check runs on every create/update of the group.","commonSituations":"Duplicating an existing re-chunking tree template inside the same group instead of a different group; copying a template's config wholesale when adding a second tree template; frontend defaulting raptor.rechunk to true on new tree templates.","solutions":["Set config.raptor.rechunk to false (or remove the key) on all but one tree template in the group before saving.","Move the second re-chunking tree template into its own compilation template group.","Audit the payload client-side before submit: count kind=='tree' entries with raptor.rechunk truthy and block the request if >1."],"exampleFix":"// before (two tree templates both with):\n{\"kind\": \"tree\", \"config\": {\"raptor\": {\"rechunk\": true}}}\n{\"kind\": \"tree\", \"config\": {\"raptor\": {\"rechunk\": true}}}\n// after\n{\"kind\": \"tree\", \"config\": {\"raptor\": {\"rechunk\": true}}}\n{\"kind\": \"tree\", \"config\": {\"raptor\": {\"rechunk\": false}}}","handlingStrategy":"validation","validationCode":"def count_rechunk_trees(templates):\n    n = 0\n    for t in templates or []:\n        if str((t or {}).get('kind') or '').strip() != 'tree':\n            continue\n        if bool(((t.get('config') or {}).get('raptor') or {}).get('rechunk')):\n            n += 1\n    return n\n\nif count_rechunk_trees(payload['templates']) > 1:\n    raise ValueError('disable rechunk on all but one tree template')","typeGuard":"def is_valid_group_rechunk(templates: list[dict]) -> bool:\n    return count_rechunk_trees(templates) <= 1","tryCatchPattern":null,"preventionTips":["UI: allow the rechunk toggle on only one tree template per group — disable it on others once one is on.","Show a live count of re-chunking tree templates next to the save button."],"tags":["validation","compilation-template","raptor","group"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}