{"record":{"id":"3072b01041b237d7","repo":"Tencent/WeKnora","slug":"w-s","errorCode":null,"errorMessage":"%w: %s","messagePattern":"%w: %s","errorType":"exception","errorClass":"errWikiPageNotFoundInScope","httpStatus":null,"severity":"error","filePath":"internal/agent/tools/wiki_route_resolver.go","lineNumber":159,"sourceCode":"\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}\n\t\treturn nil, \"\", fmt.Errorf(\"%w: slug %s belongs to %s\", errWikiPageAmbiguous, slug, strings.Join(owners, \", \"))\n\t}\n}\n\n// resolveWikiCreateKB selects a creation target only when server-side context\n// is unambiguous: one cached provenance owner or one Wiki KB in scope.\nfunc resolveWikiCreateKB(\n\tslug string,\n\tkbIDs []string,\n\troutes *WikiRouteResolver,\n\tserverHints ...string,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/tools/wiki_route_resolver.go#L141-L177","documentation":"When the slug was not found in any allowed scope, the resolver returns errWikiPageNotFoundInScope wrapped with the slug via %w: %s. Because it uses %w, callers can errors.Is(err, errWikiPageNotFoundInScope) to distinguish a clean miss from real failures (272/273). This is the resolver's canonical 'page does not exist in your allowed knowledge bases' outcome.","triggerScenarios":"resolveUniqueWikiPage iterated every ordered scope, each GetPageBySlug returned ErrWikiPageNotFound (or nil page), yielding zero hits.","commonSituations":"Typo in the slug; page deleted or renamed; page exists only in a KB outside the caller's allowed scopes; wrong KB filter passed in kbIDs.","solutions":["Confirm the slug via page listing/search in the intended KB","Check the page exists in a KB included in the allowed scopes; widen scopes if appropriate","Handle it as a typed not-found in the tool layer and surface 'page not found' to the model/user","If it was recently renamed, use the old-to-new slug mapping if one exists"],"exampleFix":"page, kbID, err := resolveUniqueWikiPage(ctx, slug, kbIDs, routes)\nif err != nil && errors.Is(err, errWikiPageNotFoundInScope) {\n    return &types.ToolResult{Success: false, Error: fmt.Sprintf(\"wiki page %q not found in accessible knowledge bases\", slug)}, nil\n}","handlingStrategy":"type-guard","validationCode":"null","typeGuard":"func isWikiPageNotFoundInScope(err error) bool { return errors.Is(err, errWikiPageNotFoundInScope) }","tryCatchPattern":"page, kbID, err := resolveUniqueWikiPage(ctx, slug, kbIDs, routes)\nif err != nil && errors.Is(err, errWikiPageNotFoundInScope) {\n    return &types.ToolResult{Success: false, Error: fmt.Sprintf(\"page %q not found in allowed knowledge bases\", slug)}, nil\n}","preventionTips":["Use errors.Is on the sentinel, never string matching","Confirm the slug against a page listing before mutations","Include the intended KB in scopes so lookups are deterministic","Treat as permanent miss; avoid retry loops"],"tags":["go","wiki","not-found","sentinel-error"],"backgroundTag":"wiki-page-not-found","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}