{"record":{"id":"72a28de3ab2a9014","repo":"Tencent/WeKnora","slug":"failed-to-get-knowledge-w","errorCode":null,"errorMessage":"failed to get knowledge: %w","messagePattern":"failed to get knowledge: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/knowledge_faq_import.go","lineNumber":1146,"sourceCode":"\t\t}\n\t\tnewEntries = append(newEntries, entry)\n\t}\n\n\treturn newEntries, mergeOps, skippedCount, nil\n}\n\n// calculateReplaceOperations 计算Replace模式下需要删除、创建、更新的条目\n// 同时过滤掉同批次内标准问或相似问重复的条目\nfunc (s *knowledgeService) calculateReplaceOperations(ctx context.Context,\n\ttenantID uint64, knowledgeID string, newEntries []types.FAQEntryPayload,\n) ([]types.FAQEntryPayload, []*types.Chunk, int, error) {\n\t// 获取 kbID 用于解析 tag\n\tvar kbID string\n\tif len(newEntries) > 0 {\n\t\t// 从 knowledgeID 获取 kbID\n\t\tknowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)\n\t\tif err != nil {\n\t\t\treturn nil, nil, 0, fmt.Errorf(\"failed to get knowledge: %w\", err)\n\t\t}\n\t\tif knowledge != nil {\n\t\t\tkbID = knowledge.KnowledgeBaseID\n\t\t}\n\t}\n\n\t// 计算所有新条目的 content hash，并同时构建 hash 到 entry 的映射\n\ttype entryWithHash struct {\n\t\tentry types.FAQEntryPayload\n\t\thash  string\n\t\tmeta  *types.FAQChunkMetadata\n\t}\n\tentriesWithHash := make([]entryWithHash, 0, len(newEntries))\n\tnewHashSet := make(map[string]bool)\n\t// 用于批次内标准问和相似问去重\n\tbatchQuestions := make(map[string]bool)\n\tbatchSkippedCount := 0\n","sourceCodeStart":1128,"sourceCodeEnd":1164,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/knowledge_faq_import.go#L1128-L1164","documentation":"calculateReplaceOperations wraps errors from repo.GetKnowledgeByID when resolving the knowledgeBaseID needed to parse tags for replace-mode imports. The replace flow cannot proceed without mapping knowledgeID to its KB. The root cause is preserved by %w.","triggerScenarios":"Replace-mode import with at least one new entry; GetKnowledgeByID returns an error because the knowledge row lookup fails (DB error, connection failure, context canceled). Note: knowledge==nil is tolerated (kbID stays empty), so this fires only on actual query errors.","commonSituations":"Knowledge record deleted between task enqueue and execution; database connectivity loss; replication failover mid-import.","solutions":["Check the wrapped cause in logs","Verify the knowledge record for knowledgeID exists and the DB is reachable","Re-create or re-enqueue the FAQ import task if the knowledge was deleted","Retry after restoring database health"],"exampleFix":"// before\nknowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)\nif err != nil {\n\treturn nil, nil, 0, fmt.Errorf(\"failed to get knowledge: %w\", err)\n}\n// after\nknowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)\nif err != nil {\n\tif errors.Is(err, gorm.ErrRecordNotFound) {\n\t\treturn nil, nil, 0, fmt.Errorf(\"knowledge %s not found for replace import: %w\", knowledgeID, err)\n\t}\n\treturn nil, nil, 0, fmt.Errorf(\"failed to get knowledge: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// Before enqueueing a replace-mode import, verify the knowledge exists\nk, err := repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)\nif err != nil {\n\treturn err\n}\nif k == nil || k.KnowledgeBaseID == \"\" {\n\treturn fmt.Errorf(\"knowledge %s missing or has no knowledge base; cannot run replace import\", knowledgeID)\n}","typeGuard":"func knowledgeUsable(k *types.Knowledge) bool {\n\treturn k != nil && k.KnowledgeBaseID != \"\"\n}","tryCatchPattern":"if err := runReplaceImport(ctx, req); err != nil {\n\tif strings.Contains(err.Error(), \"failed to get knowledge\") {\n\t\t// knowledge vanished between enqueue and run: surface 404 to caller\n\t\treturn werrors.NewNotFoundError(\"knowledge no longer exists\")\n\t}\n\treturn err\n}","preventionTips":["Validate knowledgeID existence when accepting replace-import requests","Use DB-level cascade/soft-delete so knowledge rows survive until tasks finish","Check for pending import tasks before deleting a knowledge record"],"tags":["database","faq-import","replace-mode"],"backgroundTag":"knowledge-lookup-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}