Skip to content

fix(doctor): avoid crash on SecretRef memory API keys#35491

Closed
dingn42 wants to merge 1 commit intoopenclaw:mainfrom
dingn42:fix/issue-35444
Closed

fix(doctor): avoid crash on SecretRef memory API keys#35491
dingn42 wants to merge 1 commit intoopenclaw:mainfrom
dingn42:fix/issue-35444

Conversation

@dingn42
Copy link
Copy Markdown
Contributor

@dingn42 dingn42 commented Mar 5, 2026

Summary

  • guard memory-search remote API key checks in openclaw doctor so non-string values do not call .trim()
  • keep existing behavior for string API keys
  • add regression coverage for SecretRef-like remote.apiKey objects

Testing

  • pnpm test -- src/commands/doctor-memory-search.test.ts

Fixes #35444

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 5, 2026

Greptile Summary

This PR fixes a crash in openclaw doctor that occurred when agents.defaults.memorySearch.remote.apiKey was set to a SecretRef-like object (e.g. { fromEnv: "OPENAI_API_KEY" }) instead of a plain string. The previous one-liner resolved?.remote?.apiKey?.trim() silently calls .trim() on the object, throwing a TypeError at runtime. The fix adds a typeof remoteApiKey === "string" guard before calling .trim(), so non-string values fall through to hasApiKeyForProvider, which already handles SecretRef resolution correctly.

Key changes:

  • doctor-memory-search.ts — replace the single optional-chain expression with an explicit type guard; behavior for plain-string keys is identical.
  • doctor-memory-search.test.ts — adds a regression test asserting that a SecretRef-shaped apiKey does not crash, that resolveApiKeyForProvider is called as the fallback, and that no spurious warning is emitted.

One minor coverage gap worth noting: the "auto" provider path also uses hasRemoteApiKey in its loop (line 122), but no test covers the scenario where provider: "auto" is combined with a SecretRef apiKey. The existing fix is still correct for that path — hasRemoteApiKey evaluates to false, causing the loop to fall back to hasApiKeyForProvider per-provider — but an additional test case could make that coverage explicit.

Confidence Score: 5/5

  • This PR is safe to merge; it is a narrowly-scoped bug fix with no breaking changes and a direct regression test.
  • The change is a two-line surgical fix that only affects a single boolean derivation. The logic is correct, the existing string-key behaviour is unaffected, and a regression test directly covers the crash path. There are no architectural changes, no new dependencies, and no modifications to config schema or public API.
  • No files require special attention.

Last reviewed commit: b1ae802

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1ae80234d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const resolved = resolveMemorySearchConfig(cfg, agentId);
const hasRemoteApiKey = Boolean(resolved?.remote?.apiKey?.trim());
const remoteApiKey = resolved?.remote?.apiKey;
const hasRemoteApiKey = typeof remoteApiKey === "string" && remoteApiKey.trim().length > 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat SecretRef memory API keys as configured

noteMemorySearchHealth now only treats remote.apiKey as present when it is a string, so a valid SecretRef object on agents.*.memorySearch.remote.apiKey is classified as missing and falls through to hasApiKeyForProvider(...). In setups that rely on SecretRef-backed memory credentials (supported by the config schema via SecretInputSchema), openclaw doctor will incorrectly emit the “no API key was found” warning whenever no profile/env key is present, even though memory search is configured. This should use a SecretInput-aware presence check instead of a string-only trim check.

Useful? React with 👍 / 👎.

@joshavant
Copy link
Copy Markdown
Contributor

Thanks for the contribution here, and for helping narrow down the SecretRef doctor crash.

We merged #36835, which supersedes this PR and fixes the broader doctor/memory SecretRef surface in one place, including the related runtime embedding paths.

I’m closing this as superseded by #36835, but I appreciate the fix and the investigation that went into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openclaw doctor crashes with TypeError on SecretRef/vault-resolved apiKey values

2 participants