Tencent/WeKnora · error

failed to get knowledge: %w

Error message

failed to get knowledge: %w

What it means

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.

Source

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

		}
		newEntries = append(newEntries, entry)
	}

	return newEntries, mergeOps, skippedCount, nil
}

// calculateReplaceOperations 计算Replace模式下需要删除、创建、更新的条目
// 同时过滤掉同批次内标准问或相似问重复的条目
func (s *knowledgeService) calculateReplaceOperations(ctx context.Context,
	tenantID uint64, knowledgeID string, newEntries []types.FAQEntryPayload,
) ([]types.FAQEntryPayload, []*types.Chunk, int, error) {
	// 获取 kbID 用于解析 tag
	var kbID string
	if len(newEntries) > 0 {
		// 从 knowledgeID 获取 kbID
		knowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)
		if err != nil {
			return nil, nil, 0, fmt.Errorf("failed to get knowledge: %w", err)
		}
		if knowledge != nil {
			kbID = knowledge.KnowledgeBaseID
		}
	}

	// 计算所有新条目的 content hash,并同时构建 hash 到 entry 的映射
	type entryWithHash struct {
		entry types.FAQEntryPayload
		hash  string
		meta  *types.FAQChunkMetadata
	}
	entriesWithHash := make([]entryWithHash, 0, len(newEntries))
	newHashSet := make(map[string]bool)
	// 用于批次内标准问和相似问去重
	batchQuestions := make(map[string]bool)
	batchSkippedCount := 0

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check the wrapped cause in logs
  2. Verify the knowledge record for knowledgeID exists and the DB is reachable
  3. Re-create or re-enqueue the FAQ import task if the knowledge was deleted
  4. Retry after restoring database health

Example fix

// before
knowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)
if err != nil {
	return nil, nil, 0, fmt.Errorf("failed to get knowledge: %w", err)
}
// after
knowledge, err := s.repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)
if err != nil {
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil, 0, fmt.Errorf("knowledge %s not found for replace import: %w", knowledgeID, err)
	}
	return nil, nil, 0, fmt.Errorf("failed to get knowledge: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Before enqueueing a replace-mode import, verify the knowledge exists
k, err := repo.GetKnowledgeByID(ctx, tenantID, knowledgeID)
if err != nil {
	return err
}
if k == nil || k.KnowledgeBaseID == "" {
	return fmt.Errorf("knowledge %s missing or has no knowledge base; cannot run replace import", knowledgeID)
}

Type guard

func knowledgeUsable(k *types.Knowledge) bool {
	return k != nil && k.KnowledgeBaseID != ""
}

Try / catch

if err := runReplaceImport(ctx, req); err != nil {
	if strings.Contains(err.Error(), "failed to get knowledge") {
		// knowledge vanished between enqueue and run: surface 404 to caller
		return werrors.NewNotFoundError("knowledge no longer exists")
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: Knowledge record deleted between task enqueue and execution; database connectivity loss; replication failover mid-import.

Related errors


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