openclaw - ✅(Solved) Fix Bug: wiki_search throws 'sharedMemoryManager.search is not a function' when search.backend=shared and corpus includes memory/all [1 pull requests, 1 comments, 2 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#75312Fetched 2026-05-01 05:35:24
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
2
Timeline (top)
cross-referenced ×2commented ×1

wiki_search throws sharedMemoryManager.search is not a function when the memory-wiki config has search.backend = "shared" and the query triggers shared memory search (corpus="all" or corpus="memory"). This causes wiki_search to return "No results" even when relevant wiki pages exist.

Error Message

  1. Observe error: sharedMemoryManager.search is not a function

Error Log

The bug: Under certain conditions (likely a race in QMD_MANAGER_CACHE / PENDING_QMD_MANAGER_CREATES lifecycle), resolveActiveMemoryManager returns a truthy object that does not have a .search method. The catch block in resolveActiveMemoryManager only catches exceptions — if the manager is resolved but structurally incomplete, it passes through without error.

  1. Catching the .search is not a function error and falling back to wiki-only results

Root Cause

The search pipeline in cli-U-95w5sY.js (function searchMemoryWiki, ~line 1430):

async function searchMemoryWiki(params) {
    // ...
    const sharedMemoryManager = shouldSearchSharedMemory(effectiveConfig, params.appConfig) 
        ? await resolveActiveMemoryManager({ appConfig, agentId, agentSessionKey }) 
        : null;
    const memoryResults = sharedMemoryManager 
        ? (await sharedMemoryManager.search(params.query, { maxResults }))
            .map((result) => toMemoryWikiSearchResult(result)) 
        : [];
    // ...
}

shouldSearchSharedMemory returns true when config.search.backend === "shared" AND (corpus === "memory" OR corpus === "all").

resolveActiveMemoryManager calls getActiveMemorySearchManager which resolves through:

  1. memory-host-search-BCvmZ1vC.jsgetActiveMemorySearchManager
  2. memory-host-search.runtime-Dzf9y-Iv.jsruntime.getMemorySearchManager(params)
  3. memory-DryePhh4.jsgetMemorySearchManager with QMD + FallbackMemoryManager chain

The QMD path in getMemorySearchManager:

  • Checks for QMD binary (not installed → returns null)
  • Falls back to getBuiltinMemorySearchManager which creates MemoryIndexManager
  • Returns { manager: <MemoryIndexManager instance> }

The bug: Under certain conditions (likely a race in QMD_MANAGER_CACHE / PENDING_QMD_MANAGER_CREATES lifecycle), resolveActiveMemoryManager returns a truthy object that does not have a .search method. The catch block in resolveActiveMemoryManager only catches exceptions — if the manager is resolved but structurally incomplete, it passes through without error.

Specifically, in the FallbackMemoryManager constructor path:

cacheEntry = {
    identityKey: expectedIdentityKey,
    manager: new FallbackMemoryManager({ primary, fallbackFactory }, onClose)
};

If primary creation partially fails (QMD binary unavailable → null), the createFullQmdManager returns null, and the code falls through to getBuiltinMemorySearchManager. However, if there's a timing issue where the cache entry is partially populated, the returned object may not conform to the expected MemoryManager interface (missing .search).

Fix Action

Workaround

We currently work around this by:

  1. Only using wiki_search with default corpus="wiki" (avoids shared memory path)
  2. Using memory_recall for semantic search (separate pipeline, works reliably)
  3. Using grep -rl + wiki_get as fallback when wiki_search fails

PR fix notes

PR #1: fix(memory-wiki): guard malformed shared memory manager in wiki_search

Description (problem / solution / changelog)

Closes #75312

Guards sharedMemoryManager.search in searchMemoryWiki so a third-party active memory plugin (e.g. memory-lancedb-pro) that registers a manager without a callable search no longer throws and kills wiki-only results when search.backend=shared and corpus includes memory or all.

Changes

  • extensions/memory-wiki/src/query.ts: new searchSharedMemorySafely helper — checks typeof manager.search === 'function', wraps call in try/catch, logs warning, returns [] on failure so wiki results are preserved.
  • extensions/memory-wiki/src/query.test.ts: two new cases (missing .search; .search rejects) asserting wiki results survive without throw.
  • CHANGELOG.md: Unreleased Fixes entry.

Validation

  • pnpm test extensions/memory-wiki/src/query.test.ts — 21/21 ✅
  • pnpm exec oxfmt --check — ✅
  • pnpm check:changed — ✅

Changed files

  • .agents/skills/blacksmith-testbox/SKILL.md (modified, +102/-20)
  • .agents/skills/clawsweeper/SKILL.md (added, +339/-0)
  • .agents/skills/clawsweeper/agents/openai.yaml (added, +4/-0)
  • .agents/skills/discord-clawd/SKILL.md (added, +37/-0)
  • .agents/skills/discord-clawd/agents/openai.yaml (added, +4/-0)
  • .agents/skills/gitcrawl/SKILL.md (added, +68/-0)
  • .agents/skills/gitcrawl/agents/openai.yaml (added, +4/-0)
  • .agents/skills/openclaw-pr-maintainer/SKILL.md (modified, +33/-10)
  • .agents/skills/openclaw-pre-release-plugin-testing/SKILL.md (added, +234/-0)
  • .agents/skills/openclaw-pre-release-plugin-testing/agents/openai.yaml (added, +4/-0)
  • .agents/skills/openclaw-qa-testing/SKILL.md (modified, +18/-0)
  • .agents/skills/openclaw-release-maintainer/SKILL.md (modified, +18/-8)
  • .agents/skills/openclaw-test-performance/SKILL.md (modified, +142/-10)
  • .agents/skills/openclaw-test-performance/agents/openai.yaml (modified, +2/-2)
  • .agents/skills/openclaw-testing/SKILL.md (modified, +405/-9)
  • .agents/skills/tag-duplicate-prs-issues/SKILL.md (modified, +59/-105)
  • .agents/skills/tag-duplicate-prs-issues/agents/openai.yaml (modified, +2/-2)
  • .crabbox.yaml (added, +46/-0)
  • .github/CODEOWNERS (modified, +43/-41)
  • .github/actionlint.yaml (modified, +1/-0)
  • .github/actions/docker-e2e-plan/action.yml (modified, +5/-1)
  • .github/actions/setup-node-env/action.yml (modified, +2/-0)
  • .github/codeql/codeql-actions-critical-security.yml (added, +21/-0)
  • .github/codeql/codeql-agent-runtime-boundary-critical-quality.yml (added, +53/-0)
  • .github/codeql/codeql-android-critical-security.yml (added, +30/-0)
  • .github/codeql/codeql-channel-runtime-boundary-critical-quality.yml (added, +56/-0)
  • .github/codeql/codeql-channel-runtime-boundary-critical-security.yml (added, +48/-0)
  • .github/codeql/codeql-config-boundary-critical-quality.yml (added, +33/-0)
  • .github/codeql/codeql-core-auth-secrets-critical-quality.yml (added, +53/-0)
  • .github/codeql/codeql-core-auth-secrets-critical-security.yml (added, +55/-0)
  • .github/codeql/codeql-gateway-runtime-boundary-critical-quality.yml (added, +37/-0)
  • .github/codeql/codeql-javascript-typescript.yml (removed, +0/-21)
  • .github/codeql/codeql-macos-critical-security.yml (added, +17/-0)
  • .github/codeql/codeql-mcp-process-runtime-boundary-critical-quality.yml (added, +35/-0)
  • .github/codeql/codeql-mcp-process-tool-boundary-critical-security.yml (added, +56/-0)
  • .github/codeql/codeql-memory-runtime-boundary-critical-quality.yml (added, +41/-0)
  • .github/codeql/codeql-network-ssrf-boundary-critical-security.yml (added, +41/-0)
  • .github/codeql/codeql-plugin-boundary-critical-quality.yml (added, +76/-0)
  • .github/codeql/codeql-plugin-sdk-package-contract-critical-quality.yml (added, +36/-0)
  • .github/codeql/codeql-plugin-sdk-reply-runtime-critical-quality.yml (added, +44/-0)
  • .github/codeql/codeql-plugin-trust-boundary-critical-security.yml (added, +87/-0)
  • .github/codeql/codeql-provider-runtime-boundary-critical-quality.yml (added, +44/-0)
  • .github/codeql/codeql-session-diagnostics-boundary-critical-quality.yml (added, +48/-0)
  • .github/codeql/codeql-ui-control-plane-critical-quality.yml (added, +36/-0)
  • .github/codeql/codeql-web-media-runtime-boundary-critical-quality.yml (added, +39/-0)
  • .github/images/live-media-runner/Dockerfile (added, +16/-0)
  • .github/labeler.yml (modified, +35/-0)
  • .github/workflows/ci-build-artifacts-testbox.yml (added, +224/-0)
  • .github/workflows/ci-check-testbox.yml (modified, +29/-2)
  • .github/workflows/ci.yml (modified, +162/-244)
  • .github/workflows/clawsweeper-dispatch.yml (added, +103/-0)
  • .github/workflows/codeql-android-critical-security.yml (added, +51/-0)
  • .github/workflows/codeql-critical-quality.yml (added, +619/-0)
  • .github/workflows/codeql-macos-critical-security.yml (added, +89/-0)
  • .github/workflows/codeql.yml (modified, +54/-100)
  • .github/workflows/control-ui-locale-refresh.yml (modified, +1/-1)
  • .github/workflows/crabbox-hydrate.yml (added, +109/-0)
  • .github/workflows/docker-release.yml (modified, +1/-0)
  • .github/workflows/docs-agent.yml (modified, +1/-1)
  • .github/workflows/docs-translate-trigger-release.yml (modified, +4/-0)
  • .github/workflows/full-release-validation.yml (added, +785/-0)
  • .github/workflows/install-smoke.yml (modified, +210/-67)
  • .github/workflows/labeler.yml (modified, +26/-1)
  • .github/workflows/live-media-runner-image.yml (added, +54/-0)
  • .github/workflows/macos-release.yml (modified, +12/-3)
  • .github/workflows/maintainer-command-reactions.yml (added, +99/-0)
  • .github/workflows/npm-telegram-beta-e2e.yml (modified, +97/-11)
  • .github/workflows/openclaw-cross-os-release-checks-reusable.yml (modified, +117/-8)
  • .github/workflows/openclaw-live-and-e2e-checks-reusable.yml (modified, +1505/-138)
  • .github/workflows/openclaw-release-checks.yml (modified, +492/-85)
  • .github/workflows/openclaw-scheduled-live-checks.yml (modified, +1/-0)
  • .github/workflows/opengrep-precise-full.yml (added, +70/-0)
  • .github/workflows/opengrep-precise.yml (added, +100/-0)
  • .github/workflows/package-acceptance.yml (added, +549/-0)
  • .github/workflows/parity-gate.yml (modified, +4/-2)
  • .github/workflows/plugin-clawhub-release.yml (modified, +10/-5)
  • .github/workflows/plugin-npm-release.yml (modified, +6/-3)
  • .github/workflows/plugin-prerelease.yml (added, +414/-0)
  • .github/workflows/qa-live-transports-convex.yml (modified, +131/-20)
  • .github/workflows/stale.yml (modified, +291/-18)
  • .github/workflows/test-performance-agent.yml (modified, +1/-1)
  • .gitignore (modified, +8/-0)
  • .oxlintrc.json (modified, +1/-0)
  • .semgrepignore (added, +95/-0)
  • AGENTS.md (modified, +14/-4)
  • CHANGELOG.md (modified, +955/-21)
  • CONTRIBUTING.md (modified, +1/-1)
  • Dockerfile (modified, +37/-5)
  • Dockerfile.sandbox (modified, +1/-1)
  • Dockerfile.sandbox-browser (modified, +1/-1)
  • SECURITY.md (modified, +98/-48)
  • Swabble/Package.resolved (modified, +7/-43)
  • Swabble/Package.swift (modified, +2/-3)
  • Swabble/Sources/SwabbleCore/Support/AttributedString+Sentences.swift (modified, +9/-1)
  • Swabble/Sources/SwabbleCore/Support/OutputFormat.swift (modified, +27/-21)
  • Swabble/Sources/SwabbleKit/WakeWordGate.swift (modified, +14/-11)
  • Swabble/Sources/swabble/Commands/TranscribeCommand.swift (modified, +1/-0)
  • Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift (modified, +12/-12)
  • Swabble/Tests/swabbleTests/ConfigTests.swift (modified, +15/-16)
  • appcast.xml (modified, +853/-324)

Code Example

2026-04-30T15:55:00.425-04:00 [tools] wiki_search failed: sharedMemoryManager.search is not a function raw_params={"query":"passive transfer","corpus":"all"}

---

async function searchMemoryWiki(params) {
    // ...
    const sharedMemoryManager = shouldSearchSharedMemory(effectiveConfig, params.appConfig) 
        ? await resolveActiveMemoryManager({ appConfig, agentId, agentSessionKey }) 
        : null;
    const memoryResults = sharedMemoryManager 
        ? (await sharedMemoryManager.search(params.query, { maxResults }))
            .map((result) => toMemoryWikiSearchResult(result)) 
        : [];
    // ...
}

---

cacheEntry = {
    identityKey: expectedIdentityKey,
    manager: new FallbackMemoryManager({ primary, fallbackFactory }, onClose)
};

---

{
  "plugins": {
    "slots": { "memory": "memory-lancedb-pro" },
    "entries": {
      "memory-wiki": {
        "enabled": true,
        "config": {
          "vaultMode": "isolated",
          "vault": { "path": "/home/david/.openclaw/workspace/wiki", "renderMode": "native" },
          "search": { "backend": "shared", "corpus": "wiki" }
        }
      },
      "memory-lancedb-pro": {
        "enabled": true,
        "config": {
          "embedding": {
            "provider": "openai-compatible",
            "model": "BAAI/bge-m3",
            "dimensions": 1024
          },
          "dbPath": "~/.openclaw/memory/lancedb-pro",
          "autoCapture": true,
          "autoRecall": true
        }
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug Report

Summary

wiki_search throws sharedMemoryManager.search is not a function when the memory-wiki config has search.backend = "shared" and the query triggers shared memory search (corpus="all" or corpus="memory"). This causes wiki_search to return "No results" even when relevant wiki pages exist.

Environment

  • OpenClaw version: 2026.4.23 (a979721)
  • OS: Ubuntu 24.04 (Linux 6.17.0-14-generic, x64)
  • Node: v22.22.1
  • Memory plugin: memory-lancedb-pro (BAAI/bge-m3 embeddings via SiliconFlow, LanceDB backend)
  • Memory-wiki config: vaultMode=isolated, search.backend=shared, search.corpus=wiki

Reproduction

  1. Configure memory-wiki with search.backend = "shared" and search.corpus = "wiki" (default)
  2. Call wiki_search with corpus="all" (or corpus="memory")
  3. Observe error: sharedMemoryManager.search is not a function

Error Log

2026-04-30T15:55:00.425-04:00 [tools] wiki_search failed: sharedMemoryManager.search is not a function raw_params={"query":"passive transfer","corpus":"all"}

Root Cause Analysis

The search pipeline in cli-U-95w5sY.js (function searchMemoryWiki, ~line 1430):

async function searchMemoryWiki(params) {
    // ...
    const sharedMemoryManager = shouldSearchSharedMemory(effectiveConfig, params.appConfig) 
        ? await resolveActiveMemoryManager({ appConfig, agentId, agentSessionKey }) 
        : null;
    const memoryResults = sharedMemoryManager 
        ? (await sharedMemoryManager.search(params.query, { maxResults }))
            .map((result) => toMemoryWikiSearchResult(result)) 
        : [];
    // ...
}

shouldSearchSharedMemory returns true when config.search.backend === "shared" AND (corpus === "memory" OR corpus === "all").

resolveActiveMemoryManager calls getActiveMemorySearchManager which resolves through:

  1. memory-host-search-BCvmZ1vC.jsgetActiveMemorySearchManager
  2. memory-host-search.runtime-Dzf9y-Iv.jsruntime.getMemorySearchManager(params)
  3. memory-DryePhh4.jsgetMemorySearchManager with QMD + FallbackMemoryManager chain

The QMD path in getMemorySearchManager:

  • Checks for QMD binary (not installed → returns null)
  • Falls back to getBuiltinMemorySearchManager which creates MemoryIndexManager
  • Returns { manager: <MemoryIndexManager instance> }

The bug: Under certain conditions (likely a race in QMD_MANAGER_CACHE / PENDING_QMD_MANAGER_CREATES lifecycle), resolveActiveMemoryManager returns a truthy object that does not have a .search method. The catch block in resolveActiveMemoryManager only catches exceptions — if the manager is resolved but structurally incomplete, it passes through without error.

Specifically, in the FallbackMemoryManager constructor path:

cacheEntry = {
    identityKey: expectedIdentityKey,
    manager: new FallbackMemoryManager({ primary, fallbackFactory }, onClose)
};

If primary creation partially fails (QMD binary unavailable → null), the createFullQmdManager returns null, and the code falls through to getBuiltinMemorySearchManager. However, if there's a timing issue where the cache entry is partially populated, the returned object may not conform to the expected MemoryManager interface (missing .search).

Observed Behavior

  • wiki_search with corpus="wiki" (default): works via local BM25/wiki corpus search only
  • wiki_search with corpus="all" or "memory": triggers shared memory path → crashes → returns empty results
  • memory_recall tool: works correctly (uses a different search pipeline)
  • After wiki page translations (Chinese → English), BM25 keyword matching improved but semantic vector search via wiki_search remains broken for conceptual queries

Expected Behavior

wiki_search should gracefully handle cases where the shared memory manager is unavailable, either by:

  1. Catching the .search is not a function error and falling back to wiki-only results
  2. Validating that the resolved manager has a .search method before calling it
  3. Returning wiki corpus results without shared memory augmentation when the shared path fails

Workaround

We currently work around this by:

  1. Only using wiki_search with default corpus="wiki" (avoids shared memory path)
  2. Using memory_recall for semantic search (separate pipeline, works reliably)
  3. Using grep -rl + wiki_get as fallback when wiki_search fails

Related

  • #72717 (Feature Request: SQLite FTS index for wiki_search) — related performance/request
  • Note: Our wiki vault has ~50 pages, not 80+, so this is not a scale issue — it's a runtime/lifecycle bug

Config Reference (sanitized)

{
  "plugins": {
    "slots": { "memory": "memory-lancedb-pro" },
    "entries": {
      "memory-wiki": {
        "enabled": true,
        "config": {
          "vaultMode": "isolated",
          "vault": { "path": "/home/david/.openclaw/workspace/wiki", "renderMode": "native" },
          "search": { "backend": "shared", "corpus": "wiki" }
        }
      },
      "memory-lancedb-pro": {
        "enabled": true,
        "config": {
          "embedding": {
            "provider": "openai-compatible",
            "model": "BAAI/bge-m3",
            "dimensions": 1024
          },
          "dbPath": "~/.openclaw/memory/lancedb-pro",
          "autoCapture": true,
          "autoRecall": true
        }
      }
    }
  }
}

extent analysis

TL;DR

The most likely fix is to validate that the resolved shared memory manager has a .search method before calling it to prevent the sharedMemoryManager.search is not a function error.

Guidance

  1. Validate the shared memory manager: Before calling sharedMemoryManager.search, check if the sharedMemoryManager object has a .search method to prevent the error.
  2. Catch and handle the error: Modify the catch block in resolveActiveMemoryManager to also handle cases where the manager is resolved but structurally incomplete.
  3. Improve the FallbackMemoryManager constructor: Ensure that the FallbackMemoryManager constructor returns a complete object with the expected MemoryManager interface, including the .search method.
  4. Consider a fallback search: If the shared memory manager is unavailable, fall back to wiki-only results or use a different search pipeline.

Example

if (sharedMemoryManager && typeof sharedMemoryManager.search === 'function') {
    const memoryResults = await sharedMemoryManager.search(params.query, { maxResults });
    // ...
} else {
    // Handle the case where sharedMemoryManager is missing the .search method
    // or fall back to wiki-only results
}

Notes

The provided guidance assumes that the issue is related to the shared memory manager and its .search method. However, without more information about the specific requirements and constraints of the system, it's difficult to provide a more detailed solution.

Recommendation

Apply a workaround by validating the shared memory manager and handling the error, as this is a more immediate and targeted solution to the problem.

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

openclaw - ✅(Solved) Fix Bug: wiki_search throws 'sharedMemoryManager.search is not a function' when search.backend=shared and corpus includes memory/all [1 pull requests, 1 comments, 2 participants]