Tencent/WeKnora · error

scan for duplicate memory: %w

Error message

scan for duplicate memory: %w

What it means

Wraps a failure from repo.ListLive while scanning live memory items of the same kind to find a duplicate whose content contains (or is contained by) the new content. Without the candidate list the containment-deduplication pass cannot run, so the operation aborts.

Source

Thrown at internal/application/service/memory/service.go:428

	// and the backfill pass picks up whatever this missed.
	s.storeItemEmbedding(ctx, scope, cfg, stored)
	return stored, nil
}

// findContainedDuplicate looks for a live memory of the same kind whose
// statement contains, or is contained by, the incoming one.
//
// Containment is deliberately the whole rule. It is cheap, explainable to a
// user reading their own memory list, and it cannot merge two statements that
// merely share a topic — only ones where the shorter adds nothing the longer
// does not already say. The returned bool reports whether the new statement is
// the longer of the two.
func (s *Service) findContainedDuplicate(
	ctx context.Context, scope interfaces.MemoryScope, kind, content string,
) (*types.MemoryItem, bool, error) {
	candidates, err := s.repo.ListLive(ctx, scope, kind, 200)
	if err != nil {
		return nil, false, fmt.Errorf("scan for duplicate memory: %w", err)
	}
	normalized := types.NormalizeMemoryForMatch(content)
	if normalized == "" {
		return nil, false, nil
	}
	for _, candidate := range candidates {
		if candidate == nil {
			continue
		}
		existing := types.NormalizeMemoryForMatch(candidate.Content)
		if existing == "" {
			continue
		}
		if strings.Contains(existing, normalized) {
			return candidate, false, nil
		}
		if strings.Contains(normalized, existing) {
			return candidate, true, nil

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check the wrapped repo error and fix the underlying ListLive query failure.
  2. Ensure memory_items table indexes exist for scope+kind+live lookups to avoid timeouts.
  3. Verify DB connectivity and pool settings.
  4. Retry the write once the repository is healthy; the scan is read-only and safe to repeat.
Defensive patterns

Strategy: try-catch

Try / catch

res, err := svc.write(ctx, scope, kind, content)
if err != nil {
    if errors.Is(err, context.Canceled) { return err }
    log.Warn("duplicate scan failed; proceeding without containment dedup")
}

Prevention

When it happens

Trigger: findContainedDuplicate invoked from write when repo.ListLive(ctx, scope, kind, 200) returns an error — DB connectivity issue, timeout, or query failure on the memory items table.

Common situations: Heavy memory table causing ListLive timeouts; DB failover during a write; misconfigured memory scope leading to a query error.

Related errors


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