{"record":{"id":"58baa2ef08c33495","repo":"Tencent/WeKnora","slug":"failed-to-ensure-faq-knowledge-w","errorCode":null,"errorMessage":"failed to ensure FAQ knowledge: %w","messagePattern":"failed to ensure FAQ knowledge: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/knowledge_faq.go","lineNumber":180,"sourceCode":"\t}\n\n\t// 同一标准问的并发创建必须串行：下面的重复校验只看得到已落库的条目，\n\t// 拦不住还在索引中的兄弟请求（上游超时重试就会造出这种并发）。\n\treleaseGuard, err := s.acquireFAQCreateGuard(ctx, tenantID, kb.ID, meta.StandardQuestion)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer releaseGuard()\n\n\t// 检查标准问和相似问是否与其他条目重复\n\tif err := s.checkFAQQuestionDuplicate(ctx, tenantID, kb.ID, \"\", meta); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// 确保FAQ Knowledge存在\n\tfaqKnowledge, err := s.ensureFAQKnowledge(ctx, tenantID, kb)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to ensure FAQ knowledge: %w\", err)\n\t}\n\n\t// 获取索引模式\n\tindexMode := types.FAQIndexModeQuestionOnly\n\tif kb.FAQConfig != nil && kb.FAQConfig.IndexMode != \"\" {\n\t\tindexMode = kb.FAQConfig.IndexMode\n\t}\n\n\t// 获取embedding模型\n\tembeddingModel, err := s.modelService.GetEmbeddingModel(ctx, kb.EmbeddingModelID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get embedding model: %w\", err)\n\t}\n\n\t// 创建chunk\n\tisEnabled := true\n\tif payload.IsEnabled != nil {\n\t\tisEnabled = *payload.IsEnabled","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/knowledge_faq.go#L162-L198","documentation":"CreateFAQEntry wraps any failure from ensureFAQKnowledge, which finds or lazily creates the hidden internal Knowledge record that backs a FAQ knowledge base. It surfaces underlying DB errors (findFAQKnowledge query failure or CreateKnowledge insert failure) with this prefix. It means the FAQ container knowledge could not be located or created, so no entry can be stored.","triggerScenarios":"Calling CreateFAQEntry on a valid FAQ knowledge base when the internal FAQ knowledge lookup/creation fails: database connectivity loss, deadlock or unique-key race between two concurrent creates both trying to insert the implicit FAQ knowledge row, or a repository timeout.","commonSituations":"Database under heavy load or during failover; two requests racing to create the implicit FAQ knowledge for a freshly created KB; misconfigured DB credentials/pool exhaustion causing connection errors; schema migration drift where the knowledge table is missing or locked.","solutions":["Check database connectivity/health and retry CreateFAQEntry; this is usually a transient DB error surfaced by the wrapped cause.","Inspect the wrapped cause (%w) in logs to distinguish lookup failure vs insert failure and fix accordingly (e.g. resolve unique-constraint conflict).","Avoid firing concurrent CreateFAQEntry calls against a brand-new FAQ knowledge base before the implicit FAQ knowledge row exists; serialize creation or pre-create the knowledge.","Verify schema/migrations are up to date for the knowledge table."],"exampleFix":"// before\nfaqKnowledge, err := s.ensureFAQKnowledge(ctx, tenantID, kb)\nif err != nil {\n\treturn nil, fmt.Errorf(\"failed to ensure FAQ knowledge: %w\", err)\n}\n// after (caller-side retry for transient DB errors)\nentry, err := svc.CreateFAQEntry(ctx, kbID, payload)\nif err != nil && isTransientDBError(err) {\n\ttime.Sleep(backoff)\n\tentry, err = svc.CreateFAQEntry(ctx, kbID, payload)\n}","handlingStrategy":"retry","validationCode":"// pre-check DB reachability and KB validity before creating\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database unavailable, postpone FAQ create: %w\", err)\n}\nif _, err := svc.GetKnowledgeBase(ctx, kbID); err != nil {\n\treturn fmt.Errorf(\"KB invalid: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"entry, err := svc.CreateFAQEntry(ctx, kbID, payload)\nif err != nil && strings.Contains(err.Error(), \"failed to ensure FAQ knowledge\") {\n\t// transient DB problem: back off and retry once\n\ttime.Sleep(2 * time.Second)\n\tentry, err = svc.CreateFAQEntry(ctx, kbID, payload)\n}","preventionTips":["Avoid concurrent creates against a brand-new FAQ KB until its implicit knowledge row exists","Monitor DB health and pool saturation; alert on connection errors","Keep schema migrations current for the knowledge table","Serialize creation flows for newly created knowledge bases"],"tags":["database","faq","go","wrapped-error"],"backgroundTag":"faq-knowledge-bootstrap-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}