openclaw - 💡(How to fix) Fix fix: graph-memory embedFn not passed to recall causing vector search to fail [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63458Fetched 2026-04-09 07:53:30
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
closed ×1

The embedFn (embedding function) is not being passed to the Recaller instance in graph-memory plugin, causing vector search to always fall back to keyword search even when embeddings are available.

Root Cause

In index.ts, recaller is created as a closure variable, then setEmbedFn(fn) is called asynchronously. However, when recall(query) is called later, it uses a separate Recaller instance instead of the one with embedFn set.

Fix Action

Fix

Use the same recaller instance for both setting embedFn and calling recall:

// index.ts - fixed code
let recaller: Recaller;  // module-level variable

async function onModuleInit() {
  recaller = new Recaller(...);  // Line 107
  await recaller.setEmbedFn(embedFn);
}

async function recall(query: string) {
  // Use the same recaller instance
  return recaller.recall(query);  // Fixed: use closure variable
}

Code Example

// index.ts - original buggy code
let recaller: Recaller;  // module-level variable

async function onModuleInit() {
  recaller = new Recaller(...);  // Line 107: create instance
  await recaller.setEmbedFn(embedFn);  // Line 117: async set embedFn
}

async function recall(query: string) {
  const recaller = new Recaller(...);  // Bug: creates NEW instance! (Line 199)
  // ... recaller doesn't have embedFn set
}

---

// index.ts - fixed code
let recaller: Recaller;  // module-level variable

async function onModuleInit() {
  recaller = new Recaller(...);  // Line 107
  await recaller.setEmbedFn(embedFn);
}

async function recall(query: string) {
  // Use the same recaller instance
  return recaller.recall(query);  // Fixed: use closure variable
}

---

2026-04-09T08:51:00 [plugins] [graph-memory] recall query: ... (embed=true)
2026-04-09T08:51:00 [plugins] [graph-memory] recalled 12 nodes, 3 edges
RAW_BUFFERClick to expand / collapse

Summary

The embedFn (embedding function) is not being passed to the Recaller instance in graph-memory plugin, causing vector search to always fall back to keyword search even when embeddings are available.

Root Cause

In index.ts, recaller is created as a closure variable, then setEmbedFn(fn) is called asynchronously. However, when recall(query) is called later, it uses a separate Recaller instance instead of the one with embedFn set.

Code Flow (Before Fix)

// index.ts - original buggy code
let recaller: Recaller;  // module-level variable

async function onModuleInit() {
  recaller = new Recaller(...);  // Line 107: create instance
  await recaller.setEmbedFn(embedFn);  // Line 117: async set embedFn
}

async function recall(query: string) {
  const recaller = new Recaller(...);  // Bug: creates NEW instance! (Line 199)
  // ... recaller doesn't have embedFn set
}

Fix

Use the same recaller instance for both setting embedFn and calling recall:

// index.ts - fixed code
let recaller: Recaller;  // module-level variable

async function onModuleInit() {
  recaller = new Recaller(...);  // Line 107
  await recaller.setEmbedFn(embedFn);
}

async function recall(query: string) {
  // Use the same recaller instance
  return recaller.recall(query);  // Fixed: use closure variable
}

Verification

After fix, logs show (embed=true) indicating vector search is active:

2026-04-09T08:51:00 [plugins] [graph-memory] recall query: ... (embed=true)
2026-04-09T08:51:00 [plugins] [graph-memory] recalled 12 nodes, 3 edges

Files Changed

  • plugins/graph-memory/src/index.ts - use module-level recaller in recall()
  • plugins/graph-memory/src/recall.ts - add hasEmbed getter for debugging

Labels

bug

extent analysis

TL;DR

To fix the issue, use the same recaller instance for both setting embedFn and calling recall by removing the creation of a new Recaller instance in the recall function.

Guidance

  • Identify where the recaller instance is created and ensure it's the same instance used throughout the code.
  • Verify that setEmbedFn is called before recall to ensure embedFn is properly set.
  • Check the logs for (embed=true) to confirm vector search is active after applying the fix.
  • Review the changes made to index.ts and recall.ts to understand the fix implementation.

Example

The fixed code snippet shows how to use the same recaller instance:

async function recall(query: string) {
  return recaller.recall(query);  // Use the same recaller instance
}

Notes

This fix assumes that the onModuleInit function is called before the recall function, ensuring that setEmbedFn is executed before recall. If this is not the case, additional synchronization may be necessary.

Recommendation

Apply the workaround by using the same recaller instance, as this directly addresses the identified issue and ensures that embedFn is properly set for vector search.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING