{"record":{"id":"23d2f9022561aba4","repo":"Tencent/WeKnora","slug":"wiki-page-s-returned-knowledge-base-s-while-reso","errorCode":null,"errorMessage":"wiki page %s returned knowledge base %s while resolving allowed scope %s","messagePattern":"wiki page (.+?) returned knowledge base (.+?) while resolving allowed scope (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/wiki_route_resolver.go","lineNumber":148,"sourceCode":"\t\tkbID string\n\t}\n\tvar hits []hit\n\tfor _, scope := range ordered {\n\t\tpage, err := service.GetPageBySlug(ctx, scope.KnowledgeBaseID, slug)\n\t\tif err != nil {\n\t\t\tif errors.Is(err, repository.ErrWikiPageNotFound) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, \"\", fmt.Errorf(\n\t\t\t\t\"failed to resolve wiki page %s in knowledge base %s: %w\",\n\t\t\t\tslug, scope.KnowledgeBaseID, err,\n\t\t\t)\n\t\t}\n\t\tif page == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif page.KnowledgeBaseID != \"\" && page.KnowledgeBaseID != scope.KnowledgeBaseID {\n\t\t\treturn nil, \"\", fmt.Errorf(\n\t\t\t\t\"wiki page %s returned knowledge base %s while resolving allowed scope %s\",\n\t\t\t\tslug, page.KnowledgeBaseID, scope.KnowledgeBaseID,\n\t\t\t)\n\t\t}\n\t\tkbID := scope.KnowledgeBaseID\n\t\thits = append(hits, hit{page: page, kbID: kbID})\n\t\troutes.rememberPage(page, kbID)\n\t}\n\tswitch len(hits) {\n\tcase 0:\n\t\treturn nil, \"\", fmt.Errorf(\"%w: %s\", errWikiPageNotFoundInScope, slug)\n\tcase 1:\n\t\treturn hits[0].page, hits[0].kbID, nil\n\tdefault:\n\t\towners := make([]string, 0, len(hits))\n\t\tfor _, item := range hits {\n\t\t\towners = append(owners, item.kbID)\n\t\t}","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/tools/wiki_route_resolver.go#L130-L166","documentation":"After a successful lookup, the resolver cross-checks that the returned page's KnowledgeBaseID matches the scope it was fetched from. A mismatch means the service returned a page claiming ownership by a different KB than the explicitly authorized scope — a consistency/authorization invariant violation. The error aborts resolution rather than allowing a page outside the allowed scope.","triggerScenarios":"GetPageBySlug(ctx, scope.KnowledgeBaseID, slug) returns a page whose page.KnowledgeBaseID is non-empty and different from scope.KnowledgeBaseID.","commonSituations":"Replicated/stale data where a page was moved between KBs but cached copies still point to the old KB; service routing a slug lookup across KBs; manual data repair leaving inconsistent KnowledgeBaseID fields.","solutions":["Re-index or repair the page record so its KnowledgeBaseID matches the KB it is stored in","Investigate the service layer for cross-KB slug lookups/shortcuts returning foreign pages","Purge any stale cache that holds the old KB ownership for the moved page","If a page was legitimately moved, update references to use the new KB's scope"],"exampleFix":"// data repair\nUPDATE wiki_pages SET knowledge_base_id = '<allowed-kb-id>' WHERE slug = '<slug>' AND knowledge_base_id = '<stale-kb-id>';","handlingStrategy":"validation","validationCode":"page, err := service.GetPageBySlug(ctx, kbID, slug)\nif err == nil && page != nil && page.KnowledgeBaseID != \"\" && page.KnowledgeBaseID != kbID {\n    return fmt.Errorf(\"ownership mismatch: page in %s claims %s\", kbID, page.KnowledgeBaseID)\n}","typeGuard":"func pageOwnedBy(page *types.WikiPage, kbID string) bool {\n    return page != nil && (page.KnowledgeBaseID == \"\" || page.KnowledgeBaseID == kbID)\n}","tryCatchPattern":"page, kbID, err := resolveUniqueWikiPage(ctx, slug, kbIDs, routes)\nif err != nil && strings.Contains(err.Error(), \"while resolving allowed scope\") {\n    // flag data inconsistency to ops; do not auto-retry\n}","preventionTips":["Enforce KnowledgeBaseID consistency in the service layer before returning pages","Repair moved pages atomically (update record + cache together)","Alert on cross-KB ownership mismatches found in periodic audits","Avoid manual SQL repairs that leave stale KnowledgeBaseID values"],"tags":["go","wiki","data-consistency","authorization"],"backgroundTag":"kb-ownership-mismatch","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}