{"record":{"id":"e73e34af88a3a73b","repo":"Tencent/WeKnora","slug":"wiki-page-references-unknown-folder-q","errorCode":null,"errorMessage":"wiki page references unknown folder %q","messagePattern":"wiki page references unknown folder %q","errorType":"validation","errorClass":null,"httpStatus":404,"severity":"error","filePath":"internal/application/service/wiki_page.go","lineNumber":1393,"sourceCode":"\treturn types.CleanWikiCategoryPath(strings.Split(path, \"/\"))\n}\n\n// applyFolderToPage refreshes a page's derived category_path cache from its\n// authoritative FolderID. Root (\"\") clears the path. A folder id that does not\n// resolve is treated as a hard error so we never silently misplace a page.\nfunc (s *wikiPageService) applyFolderToPage(ctx context.Context, page *types.WikiPage) error {\n\tif page == nil {\n\t\treturn nil\n\t}\n\tif strings.TrimSpace(page.FolderID) == \"\" {\n\t\tpage.FolderID = \"\"\n\t\tpage.CategoryPath = nil\n\t\treturn nil\n\t}\n\tfolder, err := s.repo.GetFolderByID(ctx, page.KnowledgeBaseID, page.FolderID)\n\tif err != nil {\n\t\tif errors.Is(err, repository.ErrWikiFolderNotFound) {\n\t\t\treturn fmt.Errorf(\"wiki page references unknown folder %q\", page.FolderID)\n\t\t}\n\t\treturn fmt.Errorf(\"resolve page folder: %w\", err)\n\t}\n\tpage.CategoryPath = types.StringArray(wikiFolderSegments(folder.Path))\n\treturn nil\n}\n\n// GetFolder retrieves a single folder by id.\nfunc (s *wikiPageService) GetFolder(ctx context.Context, kbID string, id string) (*types.WikiFolder, error) {\n\treturn s.repo.GetFolderByID(ctx, kbID, id)\n}\n\n// ListChildFolders returns the direct children of parentID for a tree view\n// scoped to pageTypes. PageCount is recursive (the folder's whole subtree) so\n// a parent reflects everything filed beneath it. A folder is shown when its\n// subtree holds a page matching pageTypes. Wholly-empty folders (no pages of\n// any type underneath) are only listed when multiple types are requested —\n// the merged knowledge view — so single-type tabs like summary do not surface","sourceCodeStart":1375,"sourceCodeEnd":1411,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/wiki_page.go#L1375-L1411","documentation":"applyFolderToPage resolves a page's FolderID via repo.GetFolderByID. If the repository reports ErrWikiFolderNotFound, the service returns 'wiki page references unknown folder %q' — the page points at a folder that doesn't exist in that KB. It is a referential-integrity validation error, deliberately distinct from generic storage errors.","triggerScenarios":"CreatePage/UpdatePage/MovePage with a FolderID that no longer exists (or never existed) in page.KnowledgeBaseID — deleted folder, folder from another KB, or a fabricated/garbage ID.","commonSituations":"Folders deleted while clients held stale folder IDs in cached forms; copying pages between knowledge bases without remapping FolderID; frontend sending empty-string vs nil handling bugs; concurrent folder deletion and page move.","solutions":["Fetch the current folder list for the KB and pass a valid FolderID (or clear FolderID entirely).","Check whether the folder was deleted by another user and choose a new parent folder.","Ensure the FolderID belongs to the same knowledge base as the page.","Use FindOrCreateFolderPath to resolve a category path to a guaranteed-valid folder instead of raw IDs."],"exampleFix":"// before\npage.FolderID = oldFolderID // folder since deleted\nsvc.UpdatePage(ctx, page)\n// after\nfolder, err := svc.FindOrCreateFolderPath(ctx, kbID, []string{\"Docs\", \"Guides\"})\nif err != nil { return err }\npage.FolderID = folder.ID\nsvc.UpdatePage(ctx, page)","handlingStrategy":"validation","validationCode":"folders, err := svc.ListFolders(ctx, kbID)\nif err != nil { return err }\nknown := make(map[string]bool, len(folders))\nfor _, f := range folders { known[f.ID] = true }\nif page.FolderID != \"\" && !known[page.FolderID] {\n    page.FolderID = \"\" // clear stale reference instead of failing\n}","typeGuard":"func folderExists(folderID string, folders []*types.WikiFolder) bool {\n    if folderID == \"\" { return true }\n    for _, f := range folders { if f.ID == folderID { return true } }\n    return false\n}","tryCatchPattern":"_, err := svc.UpdatePage(ctx, page)\nif err != nil && strings.Contains(err.Error(), \"references unknown folder\") {\n    page.FolderID = \"\" // drop stale folder, keep the page save\n    _, err = svc.UpdatePage(ctx, page)\n}","preventionTips":["Re-fetch folder IDs at save time; never reuse IDs cached across sessions","When deleting folders, update or clear pages referencing them (cascade)","Ensure FolderID always belongs to the same KB as the page","Prefer FindOrCreateFolderPath over raw folder IDs for new pages"],"tags":["referential-integrity","folder","validation"],"backgroundTag":"broken-foreign-key-reference","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}