{"record":{"id":"66765bb2e10fef50","repo":"infiniflow/ragflow","slug":"a-wiki-template-cannot-be-combined-with-other-temp","errorCode":null,"errorMessage":"A wiki template cannot be combined with other templates in the same group.","messagePattern":"A wiki template cannot be combined with other templates in the same group\\.","errorType":"validation","errorClass":"GroupValidationError","httpStatus":null,"severity":"error","filePath":"api/db/services/compilation_template_group_service.py","lineNumber":45,"sourceCode":"\n\nclass GroupValidationError(ValueError):\n    pass\n\n\ndef _derive_scope(templates: list[dict]) -> str:\n    \"\"\"Derive the group's scope from its child templates.\n\n    One artifacts child = dataset scope (and must be the only child).\n    Otherwise file scope, with no artifacts allowed.\n    \"\"\"\n    if not templates:\n        raise GroupValidationError(\"A template group must contain at least one template.\")\n    kinds = [str((t or {}).get(\"kind\") or \"\").strip() for t in templates]\n    artifact_count = sum(1 for k in kinds if k == \"wiki\")\n    if artifact_count > 0:\n        if artifact_count != 1 or len(templates) != 1:\n            raise GroupValidationError(\"A wiki template cannot be combined with other templates in the same group.\")\n        return SCOPE_DATASET\n\n    _enforce_single_rechunk_tree(templates)\n    return SCOPE_FILE\n\n\ndef _enforce_single_rechunk_tree(templates: list[dict]) -> None:\n    \"\"\"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:","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/compilation_template_group_service.py#L27-L63","documentation":"GroupValidationError raised by _derive_scope when a group contains a wiki-kind template together with anything else (two wikis, or a wiki plus a file-scope template). A wiki template maps the group to dataset scope and must be the sole child; mixing kinds would make the scope ambiguous and is rejected before _enforce_single_rechunk_tree runs.","triggerScenarios":"Creating/updating a group whose templates array includes a kind=='wiki' entry plus any other entry; a UI bug that preselects a wiki template alongside file templates; imports merging a wiki group with a regular group.","commonSituations":"Users multi-selecting templates of mixed kinds in the group editor; default-selection state that includes a wiki template; API payloads assembled by concatenating existing groups.","solutions":["Put the wiki template in its own group (single child), and keep file-scope templates in separate groups.","Enforce the constraint in the UI: selecting a wiki template disables all other selections.","Validate server-side before save: reject if any(k=='wiki') and len(templates)!=1.","Fix import/merge logic that concatenates template lists across groups."],"exampleFix":"# before\ngroup = {\"templates\": [wiki_template, file_template]}\n\n# after\nwiki_group = {\"templates\": [wiki_template]}\nfile_group = {\"templates\": [file_template]}","handlingStrategy":"validation","validationCode":"kinds = [str((t or {}).get(\"kind\") or \"\").strip() for t in templates]\nif kinds.count(\"wiki\") > 0 and len(templates) != 1:\n    raise ValueError(\"A wiki template must be alone in its group\")","typeGuard":"def group_scope_compliant(templates: list[dict]) -> bool:\n    kinds = [str((t or {}).get(\"kind\") or \"\").strip() for t in templates]\n    return kinds.count(\"wiki\") in (0,) or (kinds.count(\"wiki\") == 1 and len(templates) == 1)","tryCatchPattern":"try:\n    create_group(name, templates)\nexcept GroupValidationError as e:\n    if \"wiki\" in str(e):\n        # split payload into a wiki-only group and a file-scope group\n        ...","preventionTips":["UI rule: selecting a wiki template clears and locks other selections.","Never merge group payloads by concatenation during imports.","One wiki per group, and it must be the only child — encode this in tests."],"tags":["validation","template-group","wiki","compilation","ragflow"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}