{"record":{"id":"3c60eaa5b7647982","repo":"Tencent/WeKnora","slug":"failed-to-update-chunk-status-w","errorCode":null,"errorMessage":"failed to update chunk status: %w","messagePattern":"failed to update chunk status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/knowledge_faq.go","lineNumber":249,"sourceCode":"\n\t// 索引chunk：交互式创建给索引步骤设硬上限，避免 embedding 抖动把请求拖长\n\tindexCtx, cancelIndex := context.WithTimeout(ctx, faqCreateIndexBudget)\n\tindexErr := s.indexFAQChunks(indexCtx, kb, faqKnowledge, []*types.Chunk{chunk}, embeddingModel, true, false)\n\tcancelIndex()\n\tif indexErr != nil {\n\t\t// 如果索引失败，删除已创建的chunk。回滚失败会留下一条 stored 状态的\n\t\t// 残留：它不出现在列表里，却会被重复校验命中，因此必须告警而非静默。\n\t\tif delErr := s.chunkService.DeleteChunk(ctx, chunk.ID); delErr != nil {\n\t\t\tlogger.Errorf(ctx,\n\t\t\t\t\"CreateFAQEntry: rollback failed, chunk %s left in stored state: %v\", chunk.ID, delErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to index chunk: %w\", indexErr)\n\t}\n\n\t// 更新chunk状态为已索引\n\tchunk.Status = int(types.ChunkStatusIndexed)\n\tif err := s.chunkService.UpdateChunk(ctx, chunk); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to update chunk status: %w\", err)\n\t}\n\n\t// Build tag seq_id map for conversion\n\ttagSeqIDMap := make(map[string]int64)\n\tif chunk.TagID != \"\" {\n\t\ttag, tagErr := s.tagRepo.GetByID(ctx, tenantID, chunk.TagID)\n\t\tif tagErr == nil && tag != nil {\n\t\t\ttagSeqIDMap[tag.ID] = tag.SeqID\n\t\t}\n\t}\n\n\t// 转换为FAQEntry返回\n\tentry, err := s.chunkToFAQEntry(chunk, kb, tagSeqIDMap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// 查询TagName","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/knowledge_faq.go#L231-L267","documentation":"After successful indexing, CreateFAQEntry flips chunk.Status to ChunkStatusIndexed and persists via chunkService.UpdateChunk; failure is wrapped with this message. The entry is already created and indexed, but its status marker remains Stored, so it may not appear in listings or may be re-indexed. This is a DB update failure, not an indexing problem.","triggerScenarios":"Calling CreateFAQEntry when the post-index UpdateChunk write fails: DB connection loss, deadlock/lock wait timeout on the chunk row, request context cancelled between index completion and the update, or optimistic-concurrency conflict if the row changed concurrently.","commonSituations":"Transient DB blip right after embedding finished; long requests whose context expires during the final write; heavy write contention on the chunk table; connection pool exhaustion.","solutions":["Check the wrapped DB error and retry the operation; if a duplicate question blocks re-creation, delete or manually flip the stale chunk's status to indexed.","Repair the inconsistent chunk directly: UPDATE the chunk status to indexed (or delete it) so listings and duplicate checks behave correctly.","Increase request timeouts to avoid context cancellation before the final status write.","Check DB lock contention/deadlocks on the chunk table under concurrent FAQ creation."],"exampleFix":"// after hitting this error, repair the stuck chunk\nchunk, _ := chunkRepo.GetByID(ctx, chunkID)\nchunk.Status = int(types.ChunkStatusIndexed)\nchunkRepo.Update(ctx, chunk) // or delete if the entry should not exist","handlingStrategy":"try-catch","validationCode":"if err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database unhealthy; FAQ create may end in inconsistent status: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"entry, err := svc.CreateFAQEntry(ctx, kbID, payload)\nif err != nil && strings.Contains(err.Error(), \"failed to update chunk status\") {\n\t// entry is indexed but status is stale; reconcile by listing/re-fetching\n\t// or delete the chunk if the entry should not exist\n\tlog.Warn(\"FAQ created but status update failed; reconcile chunk status\", \"kb\", kbID)\n}","preventionTips":["Increase request timeouts so the final status write is not cut off","Monitor chunk rows stuck in Stored status despite successful indexing","Reduce write contention on the chunk table during peak FAQ editing","Add a periodic reconciliation job fixing Stored chunks whose vectors exist"],"tags":["database","state-inconsistency","faq","go"],"backgroundTag":"chunk-status-update-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}