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, nilView on GitHub (pinned to 988cbb0330)
Solutions
- Check the wrapped repo error and fix the underlying ListLive query failure.
- Ensure memory_items table indexes exist for scope+kind+live lookups to avoid timeouts.
- Verify DB connectivity and pool settings.
- 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
- Index memory_items on (scope, kind, live) so ListLive stays fast
- Keep the live-item count per scope modest or tune the 200 limit
- Watch DB slow-query logs for ListLive timeouts
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
- check forgotten memory: %w
- check forgotten source: %w
- ensure memory subject: %w
- find conflicting memory: %w
- create memory item: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/dad189196f8dfee5.
Report an issue: GitHub.