Tencent/WeKnora · error
failed to calculate replace operations: %w
Error message
failed to calculate replace operations: %w
What it means
executeFAQImport wraps any error returned by calculateReplaceOperations when computing the delete/update diff for replace-mode imports. It is a wrapper: the real cause is errors 470-472 (knowledge lookup or chunk listing failures) raised inside that function.
Source
Thrown at internal/application/service/knowledge_faq_import.go:1410
if kb.FAQConfig != nil && kb.FAQConfig.IndexMode != "" {
indexMode = kb.FAQConfig.IndexMode
}
// 增量更新逻辑:计算需要处理的条目
var entriesToProcess []types.FAQEntryPayload
var chunksToDelete []*types.Chunk
var skippedCount int
if payload.Mode == types.FAQBatchModeReplace {
// Replace模式:计算需要删除、创建、更新的条目
entriesToProcess, chunksToDelete, skippedCount, err = s.calculateReplaceOperations(
ctx,
tenantID,
faqKnowledge.ID,
payload.Entries,
)
if err != nil {
return fmt.Errorf("failed to calculate replace operations: %w", err)
}
// 删除需要删除的chunks(包括需要更新的旧chunks)
if len(chunksToDelete) > 0 {
chunkIDsToDelete := make([]string, 0, len(chunksToDelete))
for _, chunk := range chunksToDelete {
chunkIDsToDelete = append(chunkIDsToDelete, chunk.ID)
}
if err := s.chunkRepo.DeleteChunks(ctx, tenantID, chunkIDsToDelete); err != nil {
return fmt.Errorf("failed to delete chunks: %w", err)
}
// 删除索引
if err := s.deleteFAQChunkVectors(ctx, kb, faqKnowledge, chunksToDelete); err != nil {
return fmt.Errorf("failed to delete chunk vectors: %w", err)
}
logger.Infof(ctx, "FAQ import task %s: deleted %d chunks (including updates)", taskID, len(chunksToDelete))
}
} else {View on GitHub (pinned to 988cbb0330)
Solutions
- Look for the nested cause ('failed to get knowledge' / 'failed to list existing chunks') in the wrapped error chain
- Fix the underlying repository/DB issue identified by the cause
- Retry the replace import once the database is healthy
- Split very large replace imports to keep the diff computation within timeouts
Example fix
// before
if err != nil {
return fmt.Errorf("failed to calculate replace operations: %w", err)
}
// after
if err != nil {
return fmt.Errorf("failed to calculate replace operations for task %s: %w", taskID, err)
} Defensive patterns
Strategy: retry
Validate before calling
// Verify knowledge and chunk listing succeed before invoking replace calculation
if _, err := repo.GetKnowledgeByID(ctx, tenantID, knowledgeID); err != nil {
return fmt.Errorf("preflight knowledge lookup failed: %w", err)
}
if _, err := chunkRepo.ListAllFAQChunksByKnowledgeID(ctx, tenantID, knowledgeID); err != nil {
return fmt.Errorf("preflight chunk listing failed: %w", err)
} Try / catch
err := runReplaceImport(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to calculate replace operations") {
if isTransientDBError(errors.Unwrap(err)) {
return retryWithBackoff(3, runReplaceImport, ctx, req)
}
return err
}
return err Prevention
- Fix the underlying cause (errors 470-472) — this wrapper disappears with it
- Keep replace imports per knowledge base serialized to avoid races
- Use errors.Is/As on the wrapped chain rather than string matching where possible
- Set context timeouts comfortably above diff computation time for large KBs
When it happens
Trigger: Replace-mode import (payload.IsReplace) calls calculateReplaceOperations; it returns an error from GetKnowledgeByID or ListAllFAQChunksByKnowledgeID, or any internal diff computation error.
Common situations: DB connectivity loss during replace import; knowledge record deleted mid-flight; timeout while listing all existing chunks for a large knowledge base.
Related errors
- failed to get knowledge: %w
- failed to list existing chunks: %w
- failed to resolve wiki page %s in knowledge base %s: %w
- failed to list existing FAQ chunks: %w
- panic during FAQ import: %v
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/174e1dab35dd1364.
Report an issue: GitHub.