Tencent/WeKnora · error

failed to list existing chunks: %w

Error message

failed to list existing chunks: %w

What it means

calculateReplaceOperations wraps errors from chunkRepo.ListAllFAQChunksByKnowledgeID when loading all existing FAQ chunks to match against incoming entry content hashes. Without this list the replace diff (chunks to delete/update) cannot be computed. The original DB error is preserved via %w.

Source

Thrown at internal/application/service/knowledge_faq_import.go:1210

		}

		// 将当前条目的标准问和相似问加入批次集合
		batchQuestions[meta.StandardQuestion] = true
		for _, q := range meta.SimilarQuestions {
			batchQuestions[q] = true
		}

		hash := types.CalculateFAQContentHash(meta)
		if hash != "" {
			entriesWithHash = append(entriesWithHash, entryWithHash{entry: entry, hash: hash, meta: meta})
			newHashSet[hash] = true
		}
	}

	// 查询所有已存在的chunks
	allExistingChunks, err := s.chunkRepo.ListAllFAQChunksByKnowledgeID(ctx, tenantID, knowledgeID)
	if err != nil {
		return nil, nil, 0, fmt.Errorf("failed to list existing chunks: %w", err)
	}

	// 在内存中过滤出匹配新条目hash的chunks,并构建map
	existingHashMap := make(map[string]*types.Chunk)
	for _, chunk := range allExistingChunks {
		if chunk.ContentHash != "" && newHashSet[chunk.ContentHash] {
			existingHashMap[chunk.ContentHash] = chunk
		}
	}

	// 计算需要删除的chunks(数据库中有但新批次中没有的,或hash不匹配的)
	chunksToDelete := make([]*types.Chunk, 0)
	for _, chunk := range allExistingChunks {
		if chunk.ContentHash == "" {
			// 如果没有hash,需要删除(可能是旧数据)
			chunksToDelete = append(chunksToDelete, chunk)
		} else if !newHashSet[chunk.ContentHash] {
			// hash不在新条目中,需要删除

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Inspect the wrapped cause in logs
  2. Confirm DB connectivity and query performance for ListAllFAQChunksByKnowledgeID
  3. Add/verify indexes on knowledge_id and tenant_id for the chunks table
  4. Reduce import size or increase timeouts; retry the import

Example fix

// before
allExistingChunks, err := s.chunkRepo.ListAllFAQChunksByKnowledgeID(ctx, tenantID, knowledgeID)
if err != nil {
	return nil, nil, 0, fmt.Errorf("failed to list existing chunks: %w", err)
}
// after
allExistingChunks, err := s.chunkRepo.ListAllFAQChunksByKnowledgeID(ctx, tenantID, knowledgeID)
if err != nil {
	return nil, nil, 0, fmt.Errorf("failed to list existing chunks (knowledge=%s): %w", knowledgeID, err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: confirm the knowledge has listable chunks before replace mode
chunks, err := chunkRepo.ListAllFAQChunksByKnowledgeID(ctx, tenantID, knowledgeID)
if err != nil {
	return fmt.Errorf("preflight chunk list failed: %w", err)
}
log.Printf("replace import preflight: %d existing chunks", len(chunks))

Try / catch

err := runReplaceImport(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to list existing chunks") {
	// transient DB error: bounded retry
	return retryWithBackoff(3, runReplaceImport, ctx, req)
}
return err

Prevention

When it happens

Trigger: Replace-mode import reaches the existing-chunk listing step; ListAllFAQChunksByKnowledgeID fails from DB outage, query timeout, context cancellation, or oversized result set causing memory/query limits.

Common situations: Very large FAQ knowledge bases making the full-list query slow enough to hit timeouts; DB failover; connection pool exhaustion under concurrent imports.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/c0ecc8a36fcadc91. Report an issue: GitHub.