Skip to content

fix(doctor): skip embedding provider check when QMD backend is active - #17295

Merged
Takhoffman merged 3 commits into
openclaw:mainfrom
miloudbelarebia:fix/doctor-qmd-embedding-false-positive
Feb 19, 2026
Merged

fix(doctor): skip embedding provider check when QMD backend is active#17295
Takhoffman merged 3 commits into
openclaw:mainfrom
miloudbelarebia:fix/doctor-qmd-embedding-false-positive

Conversation

@miloudbelarebia

@miloudbelarebia miloudbelarebia commented Feb 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes false positive warning in openclaw doctor when using QMD memory backend with local embeddings (e.g. embeddinggemma)
  • Adds an early return in noteMemorySearchHealth() when memory.backend === "qmd"

Fixes #17263

Problem

When QMD is configured as the memory backend, it handles embeddings internally — no separate embedding provider needs to be configured in OpenClaw's memorySearch settings. However, openclaw doctor doesn't know this and falsely warns:

Memory search is enabled but no embedding provider is configured.

Root cause

noteMemorySearchHealth() checks hasLocalEmbeddings(resolved.local) which looks for local.modelPath. QMD doesn't use this field — it bundles its own embedding model. The function then checks for remote API keys (OpenAI/Gemini/Voyage) and finds none, triggering the false positive.

Fix

Call resolveMemoryBackendConfig() at the top of the check. If backend === "qmd", return early — QMD handles its own embeddings, so no warning is needed.

1 file changed: src/commands/doctor-memory-search.ts

Test plan

  • Configure QMD as memory backend with local embeddings
  • Run openclaw doctor — verify no false warning about missing embedding provider
  • Configure builtin backend without embedding provider — verify warning still appears
  • Configure builtin backend with OpenAI key — verify no warning

Local Validation

  • pnpm check (tsgo): ✅ passes
  • pnpm test: ✅ passes (existing doctor tests still green)
  • Formatting: verified with oxfmt --check

Scope

Single-file fix: src/commands/doctor-memory-search.ts — adds early return when QMD backend is detected.

AI Assistance

AI-assisted (Claude Code) for codebase exploration and root cause analysis. The diagnostic (QMD bundles its own embeddings, so the provider check is unnecessary) and the fix approach are my own work.

Testing level: Fully tested — confirmed pnpm check and pnpm test pass locally.

Author

Miloud Belarebia@miloudbelarebia

Greptile Summary

Fixes a false positive warning in openclaw doctor when using the QMD memory backend. QMD bundles its own embedding model (e.g. embeddinggemma), so the existing embedding provider check in noteMemorySearchHealth() incorrectly flagged a missing provider. The fix adds an early return when resolveMemoryBackendConfig() reports backend === "qmd", skipping the irrelevant provider check entirely.

  • Adds resolveMemoryBackendConfig call in noteMemorySearchHealth() with early return for QMD backend
  • Adds properly hoisted mock and test case for the QMD backend path, addressing both items from prior review feedback
  • Existing tests continue to pass with a default { backend: "builtin" } mock in beforeEach

Confidence Score: 5/5

  • This PR is safe to merge — it adds a narrow, well-tested early return that only affects QMD backend users.
  • The change is minimal (one new import, one early-return guard) with clear intent. The logic is correct: MemoryBackend is a union of "builtin" | "qmd", and QMD handles its own embeddings as confirmed by the backend-config.ts source and usage in other callers like search-manager.ts. The test file properly mocks the new dependency and adds a specific test case. No regressions to existing tests since the default mock returns { backend: "builtin" }. No security concerns.
  • No files require special attention

Last reviewed commit: d970271

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@@ -22,6 +23,13 @@ export async function noteMemorySearchHealth(cfg: OpenClawConfig): Promise<void>
return;
}

// QMD backend handles embeddings internally (e.g. embeddinggemma) — no
// separate embedding provider is needed. Skip the provider check entirely.
const backendConfig = resolveMemoryBackendConfig({ cfg, agentId });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a mock for resolveMemoryBackendConfig in the test file to avoid calling the real implementation during tests

the test file (src/commands/doctor-memory-search.test.ts) doesn't mock this new import, which means tests will call the real function - this works for now but is fragile and slower than using a mock

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/doctor-memory-search.ts
Line: 28:28

Comment:
add a mock for `resolveMemoryBackendConfig` in the test file to avoid calling the real implementation during tests

the test file (`src/commands/doctor-memory-search.test.ts`) doesn't mock this new import, which means tests will call the real function - this works for now but is fragile and slower than using a mock

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +26 to +30
// QMD backend handles embeddings internally (e.g. embeddinggemma) — no
// separate embedding provider is needed. Skip the provider check entirely.
const backendConfig = resolveMemoryBackendConfig({ cfg, agentId });
if (backendConfig.backend === "qmd") {
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a test case for QMD backend to verify this early return works correctly

the test file has no coverage for the new QMD backend path - consider adding a test like:

it("does not warn when QMD backend is active", async () => {
  const cfgWithQmd = { memory: { backend: "qmd" } } as OpenClawConfig;
  resolveMemorySearchConfig.mockReturnValue({
    provider: "auto",
    local: {},
    remote: {},
  });

  await noteMemorySearchHealth(cfgWithQmd);

  expect(note).not.toHaveBeenCalled();
});
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/doctor-memory-search.ts
Line: 26:30

Comment:
add a test case for QMD backend to verify this early return works correctly

the test file has no coverage for the new QMD backend path - consider adding a test like:

```javascript
it("does not warn when QMD backend is active", async () => {
  const cfgWithQmd = { memory: { backend: "qmd" } } as OpenClawConfig;
  resolveMemorySearchConfig.mockReturnValue({
    provider: "auto",
    local: {},
    remote: {},
  });

  await noteMemorySearchHealth(cfgWithQmd);

  expect(note).not.toHaveBeenCalled();
});
```

How can I resolve this? If you propose a fix, please make it concise.

miloudbelarebia and others added 3 commits February 19, 2026 07:14
When memory.backend is set to "qmd", QMD handles embeddings internally
(e.g. via embeddinggemma) and does not require a separate embedding
provider configured through OpenClaw's memorySearch settings.

The doctor check now calls resolveMemoryBackendConfig() and returns
early when the backend is "qmd", preventing the false positive warning
"no embedding provider is configured".

Fixes openclaw#17263

Co-Authored-By: Miloud Belarebia <miloudbelarebia@users.noreply.github.com>
Address Greptile review comments: mock resolveMemoryBackendConfig to
isolate unit tests and add dedicated test verifying QMD backend skips
embedding provider checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Takhoffman
Takhoffman force-pushed the fix/doctor-qmd-embedding-false-positive branch from d970271 to 4dfb2b1 Compare February 19, 2026 13:20
@Takhoffman
Takhoffman merged commit b45bb68 into openclaw:main Feb 19, 2026
11 of 12 checks passed
@Takhoffman

Copy link
Copy Markdown
Contributor

PR #17295 - fix(doctor): skip embedding provider check when QMD backend is active (#17295)

Merged via squash.

  • Merge commit: b45bb68
  • Verified: pnpm build, pnpm check (fails on baseline formatting drift in files identical to origin/main), pnpm test:macmini
  • Changes made:
    M CHANGELOG.md
    M src/commands/doctor-memory-search.test.ts
    M src/commands/doctor-memory-search.ts
  • Why these changes were made:
    Fix the false-positive doctor warning when QMD backend is active, keep regression coverage for the QMD path, and satisfy changelog requirement for this autoland run.
  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

Thanks @miloudbelarebia!

@miloudbelarebia

Copy link
Copy Markdown
Contributor Author

Thanks @Takhoffman for the review and merge! Happy to see this landed. Looking forward to contributing more to OpenClaw.

obviyus pushed a commit that referenced this pull request Feb 19, 2026
…#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
kittipond2365 pushed a commit to kittipond2365/openclaw that referenced this pull request Feb 19, 2026
…openclaw#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
mmyyfirstb pushed a commit to mmyyfirstb/openclaw that referenced this pull request Feb 21, 2026
…openclaw#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
…openclaw#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…openclaw#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…openclaw#17295) thanks @miloudbelarebia

Verified:
- pnpm build
- pnpm check (fails on baseline formatting drift in files identical to origin/main)
- pnpm test:macmini

Co-authored-by: miloudbelarebia <52387093+miloudbelarebia@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations dedupe:parent Primary canonical item in dedupe cluster size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: openclaw doctor falsely warns about missing embedding provider when QMD local embeddings are set

3 participants