openclaw - ✅(Solved) Fix [Bug] memory-lancedb-pro and memory-openviking plugin config rejected by gateway validator [2 pull requests, 3 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

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#49495Fetched 2026-04-08 00:54:42
View on GitHub
Comments
3
Participants
2
Timeline
5
Reactions
0
Author
Participants
Timeline (top)
commented ×3cross-referenced ×1referenced ×1

The memory-lancedb-pro and memory-openviking plugins' config fields are rejected by OpenClaw's gateway-level config validator with "must NOT have additional properties" error, preventing the gateway from starting when these configs are present in openclaw.json.

Error Message

The memory-lancedb-pro and memory-openviking plugins' config fields are rejected by OpenClaw's gateway-level config validator with "must NOT have additional properties" error, preventing the gateway from starting when these configs are present in openclaw.json. result.error

Root Cause

Based on similar issues (#39535, #43551), the problem is:

  1. OpenClaw's gateway config validator does not delegate to plugin configSchema validators
  2. It validates the top-level schema and rejects any keys it doesn't recognize under plugins.entries.*
  3. Even though plugins correctly declare their config schemas, the gateway validator doesn't consult them
  4. The validator treats all plugin-specific config fields as "additional properties"

Fix Action

Workaround

Current workaround (loses all custom configuration):

  1. Backup plugin configs to a separate file
  2. Remove config fields from plugins.entries.* in openclaw.json
  3. Keep only enabled: true
  4. Restart gateway

This allows the gateway to start but memory plugins run with default settings only, losing:

  • Custom embedding providers and API endpoints
  • Database paths
  • Auto-capture/recall settings
  • Retrieval modes and reranking
  • Memory scopes and agent access controls

PR fix notes

PR #49648: fix: allow plugin apiKey and env in gateway config validator

Description (problem / solution / changelog)

Summary

  • Added apiKey and env properties to PluginEntrySchema in src/config/zod-schema.ts, matching the fields already present in SkillEntrySchema
  • The gateway config validator (Zod .strict() mode) rejected plugins.entries.*.apiKey and plugins.entries.*.env as unrecognized keys, even though the help system and labels already documented them
  • Plugin entries now accept apiKey (SecretInput), env (string record), and config (already present) without validation errors

Test plan

  • Verified OpenClawSchema.safeParse() now accepts apiKey, env, and config on plugin entries
  • Verified generated JSON schema includes all three properties
  • All existing schema tests pass (schema.help.quality, config.plugin-validation, plugins-runtime-boundary, schema, schema.hints, redact-snapshot)

Fixes #49495

🤖 Generated with Claude Code

Changed files

  • src/config/zod-schema.ts (modified, +2/-0)

PR #63013: fix(plugins): preserve explicit provider runtime ownership resolution

Description (problem / solution / changelog)

Summary

  • keep the provider runtime path short-circuited when explicit refs resolve to no owner so unrelated plugins do not broad-load under cropped config
  • preserve valid hook-only provider refs by resolving owner plugins through bundled alias mappings, active runtime aliases, and cold-start setup-registry provider metadata
  • keep explicit provider/model refs activating the owning plugin runtime instead of falling back to unrestricted loads
  • add regression coverage for the memory-lancedb-pro false-positive path plus bundled, active-runtime, and cold-start hook-alias ownership

Problem

When OpenClaw resolves explicit provider refs under a narrowed runtime config, requestedPluginIds can collapse to an empty array. The provider runtime load path then continues anyway, and that empty restriction behaves like "no restriction", so unrelated plugins get loaded and validated under cropped config.

For memory-lancedb-pro, that can surface a false invalid-config error like: embedding: must have required property 'embedding'

The first fix for that false-positive uncovered a follow-on constraint: some valid provider refs are hook-only aliases that are not directly owned by manifest providers / cliBackends. Those refs still need to resolve back to the correct plugin runtime without reintroducing the unrestricted load path.

Repro / validation

  • observed locally after upgrading to openclaw 2026.4.8
  • local hotfix removes the false warning from openclaw health
  • plugin still registers successfully after restart
  • lightweight syntax lint on the touched TS files passes locally
  • full CI will validate the updated regression matrix on the PR

Fixes #61964 Related to #62855

Changed files

  • extensions/memory-core/src/cli.test.ts (modified, +1/-0)
  • scripts/check-no-raw-channel-fetch.mjs (modified, +1/-0)
  • src/plugins/install-security-scan.runtime.ts (modified, +8/-1)
  • src/plugins/install.test.ts (modified, +1/-1)
  • src/plugins/providers.runtime.ts (modified, +152/-16)
  • src/plugins/providers.test.ts (modified, +328/-1)
  • src/plugins/providers.ts (modified, +1/-1)
  • src/plugins/setup-registry.test.ts (modified, +106/-0)
  • src/plugins/setup-registry.ts (modified, +48/-0)

Code Example

{
  "plugins": {
    "entries": {
      "memory-lancedb-pro": {
        "enabled": true,
        "config": {
          "embedding": {
            "apiKey": "${EMBEDDING_API_KEY}",
            "baseURL": "https://example.com/v1"
          },
          "dbPath": "~/.openclaw/memory/lancedb-pro",
          "autoCapture": true,
          "autoRecall": true,
          "retrieval": {
            "mode": "hybrid",
            "rerank": "lightweight"
          }
        }
      },
      "memory-openviking": {
        "enabled": true,
        "config": {
          "mode": "remote",
          "baseUrl": "http://127.0.0.1:1933",
          "targetUri": "viking://user/memories",
          "autoCapture": true,
          "autoRecall": true,
          "recallLimit": 3
        }
      }
    }
  }
}

---

Invalid config at /Users/jackmac/.openclaw/openclaw.json:
- plugins.entries.memory-lancedb-pro.config: invalid config: must NOT have additional properties
- plugins.entries.memory-openviking.config: invalid config: must NOT have additional properties

---

// In gateway config validation:
for (const [pluginId, pluginEntry] of Object.entries(config.plugins?.entries ?? {})) {
  const plugin = loadedPlugins.get(pluginId);

  if (pluginEntry.config && plugin?.configSchema) {
    const result = plugin.configSchema.safeParse(pluginEntry.config);
    if (!result.success) {
      throw new ConfigValidationError(
        `Plugin ${pluginId} config validation failed`,
        result.error
      );
    }
  }
}

---

describe("plugin config delegation", () => {
  it("accepts config fields declared in plugin configSchema", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              embedding: { apiKey: "test", baseURL: "https://example.com" },
              dbPath: "~/.openclaw/memory",
              autoCapture: true
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).not.toThrow();
  });

  it("rejects config fields that fail plugin schema validation", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              invalidField: "should fail"
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).toThrow(/invalidField/);
  });
});

---

{
  "memory-lancedb-pro": {
    "config": {
      "embedding": {
        "apiKey": "${EMBEDDING_API_KEY}",
        "baseURL": "https://custom-provider.com/v1"
      },
      "dbPath": "~/.openclaw/memory/lancedb-pro",
      "autoCapture": true,
      "autoCaptureExclude": ["raw_json", "raw_log", "health_check"],
      "autoRecall": true,
      "retrieval": {
        "mode": "hybrid",
        "rerank": "lightweight"
      },
      "scopes": {
        "default": "global",
        "definitions": {
          "global": { "description": "Shared memory" },
          "agent1": { "description": "Agent 1 memory" }
        },
        "agentAccess": {
          "main": ["global"],
          "agent1": ["global", "agent1"]
        }
      },
      "enableManagementTools": true
    }
  },
  "memory-openviking": {
    "config": {
      "mode": "remote",
      "baseUrl": "http://127.0.0.1:1933",
      "targetUri": "viking://user/memories",
      "autoCapture": true,
      "autoCaptureExclude": ["raw_json", "raw_log"],
      "autoRecall": true,
      "recallLimit": 3,
      "recallScoreThreshold": 0.3,
      "ingestReplyAssist": false
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug Report: memory-lancedb-pro and memory-openviking plugin config rejected by gateway validator

Summary

The memory-lancedb-pro and memory-openviking plugins' config fields are rejected by OpenClaw's gateway-level config validator with "must NOT have additional properties" error, preventing the gateway from starting when these configs are present in openclaw.json.

Impact

  • Gateway fails to start when memory plugin configs are present in plugins.entries.*
  • Users must choose between:
    • Running gateway without memory plugin configuration (losing custom embedding settings, scopes, retrieval modes, etc.)
    • Running openclaw doctor --fix which silently deletes the config sections
  • No workaround exists via environment variables or alternative config methods
  • This affects both memory plugins that users rely on for persistent agent memory

Environment

  • OpenClaw version: 2026.3.13 (61d171a)
  • Platform: macOS (Darwin 25.3.0)
  • Node.js: v22.x
  • Installation method: npm global install

Steps to Reproduce

  1. Fresh OpenClaw install with memory plugins enabled
  2. Add configuration to ~/.openclaw/openclaw.json:
{
  "plugins": {
    "entries": {
      "memory-lancedb-pro": {
        "enabled": true,
        "config": {
          "embedding": {
            "apiKey": "${EMBEDDING_API_KEY}",
            "baseURL": "https://example.com/v1"
          },
          "dbPath": "~/.openclaw/memory/lancedb-pro",
          "autoCapture": true,
          "autoRecall": true,
          "retrieval": {
            "mode": "hybrid",
            "rerank": "lightweight"
          }
        }
      },
      "memory-openviking": {
        "enabled": true,
        "config": {
          "mode": "remote",
          "baseUrl": "http://127.0.0.1:1933",
          "targetUri": "viking://user/memories",
          "autoCapture": true,
          "autoRecall": true,
          "recallLimit": 3
        }
      }
    }
  }
}
  1. Attempt to start gateway: openclaw gateway restart

Expected Behavior

The gateway should accept plugin config fields that are declared in each plugin's own configSchema (in their openclaw.plugin.json or equivalent), delegating validation to the plugin's schema validator.

Actual Behavior

Gateway validation fails with:

Invalid config at /Users/jackmac/.openclaw/openclaw.json:
- plugins.entries.memory-lancedb-pro.config: invalid config: must NOT have additional properties
- plugins.entries.memory-openviking.config: invalid config: must NOT have additional properties

Gateway refuses to start and suggests running openclaw doctor --fix, which silently deletes the entire config sections without user confirmation.

Root Cause Analysis

Based on similar issues (#39535, #43551), the problem is:

  1. OpenClaw's gateway config validator does not delegate to plugin configSchema validators
  2. It validates the top-level schema and rejects any keys it doesn't recognize under plugins.entries.*
  3. Even though plugins correctly declare their config schemas, the gateway validator doesn't consult them
  4. The validator treats all plugin-specific config fields as "additional properties"

Evidence from Related Issues

  • Issue #39535: acpx plugin's permissionMode config rejected
  • Issue #43551: openclaw-mem0 plugin crashes gateway — schema rejects all config keys except "enabled"
  • PR #43769: Proposed fix to "allow apiKey, env, and plugin-specific keys in plugin entry schema"

This appears to be a systemic issue affecting multiple plugins, not just memory plugins.

Proposed Fix

The gateway config validator should delegate validation of plugins.entries.<pluginId>.config to each plugin's registered configSchema.safeParse() instead of rejecting unknown keys at the top level.

Conceptual Implementation

// In gateway config validation:
for (const [pluginId, pluginEntry] of Object.entries(config.plugins?.entries ?? {})) {
  const plugin = loadedPlugins.get(pluginId);

  if (pluginEntry.config && plugin?.configSchema) {
    const result = plugin.configSchema.safeParse(pluginEntry.config);
    if (!result.success) {
      throw new ConfigValidationError(
        `Plugin ${pluginId} config validation failed`,
        result.error
      );
    }
  }
}

Test Cases

describe("plugin config delegation", () => {
  it("accepts config fields declared in plugin configSchema", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              embedding: { apiKey: "test", baseURL: "https://example.com" },
              dbPath: "~/.openclaw/memory",
              autoCapture: true
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).not.toThrow();
  });

  it("rejects config fields that fail plugin schema validation", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              invalidField: "should fail"
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).toThrow(/invalidField/);
  });
});

Workaround

Current workaround (loses all custom configuration):

  1. Backup plugin configs to a separate file
  2. Remove config fields from plugins.entries.* in openclaw.json
  3. Keep only enabled: true
  4. Restart gateway

This allows the gateway to start but memory plugins run with default settings only, losing:

  • Custom embedding providers and API endpoints
  • Database paths
  • Auto-capture/recall settings
  • Retrieval modes and reranking
  • Memory scopes and agent access controls

Additional Context

Affected Plugins (Known)

  • memory-lancedb-pro
  • memory-openviking
  • acpx (issue #39535)
  • openclaw-mem0 (issue #43551)

User Impact

This bug significantly degrades the memory plugin experience:

  • Users cannot configure custom embedding providers (critical for non-OpenAI users)
  • Cannot set up memory scopes for multi-agent systems
  • Cannot tune retrieval parameters for their use case
  • Cannot specify custom database paths (important for external storage)

Backup of Working Config

For reference, here's a working memory plugin configuration that should be supported:

{
  "memory-lancedb-pro": {
    "config": {
      "embedding": {
        "apiKey": "${EMBEDDING_API_KEY}",
        "baseURL": "https://custom-provider.com/v1"
      },
      "dbPath": "~/.openclaw/memory/lancedb-pro",
      "autoCapture": true,
      "autoCaptureExclude": ["raw_json", "raw_log", "health_check"],
      "autoRecall": true,
      "retrieval": {
        "mode": "hybrid",
        "rerank": "lightweight"
      },
      "scopes": {
        "default": "global",
        "definitions": {
          "global": { "description": "Shared memory" },
          "agent1": { "description": "Agent 1 memory" }
        },
        "agentAccess": {
          "main": ["global"],
          "agent1": ["global", "agent1"]
        }
      },
      "enableManagementTools": true
    }
  },
  "memory-openviking": {
    "config": {
      "mode": "remote",
      "baseUrl": "http://127.0.0.1:1933",
      "targetUri": "viking://user/memories",
      "autoCapture": true,
      "autoCaptureExclude": ["raw_json", "raw_log"],
      "autoRecall": true,
      "recallLimit": 3,
      "recallScoreThreshold": 0.3,
      "ingestReplyAssist": false
    }
  }
}

Related Issues

  • #39535 - acpx plugin permissionMode config rejected by gateway validator
  • #43551 - [Bug]: openclaw-mem0 plugin crashes gateway — schema rejects all config keys except "enabled"
  • #33541 - feat: SecretRef support for plugins.entries..config. (plugin config secrets)
  • #43769 - fix: allow apiKey, env, and plugin-specific keys in plugin entry schema

Request

Please prioritize this fix as it affects core memory functionality that many users depend on for persistent agent context and multi-agent systems.

Thank you for your work on OpenClaw! 🦞

extent analysis

Fix Plan

To resolve the issue, we need to update the gateway config validator to delegate validation of plugins.entries.<pluginId>.config to each plugin's registered configSchema.safeParse(). Here are the steps:

  • Update the validateConfig function in the gateway to iterate over each plugin entry and check if the plugin has a configSchema.
  • If a configSchema is found, use it to validate the plugin's config using safeParse.
  • If validation fails, throw a ConfigValidationError with the error message from the plugin's schema validation.

Example code:

// In gateway config validation:
for (const [pluginId, pluginEntry] of Object.entries(config.plugins?.entries ?? {})) {
  const plugin = loadedPlugins.get(pluginId);

  if (pluginEntry.config && plugin?.configSchema) {
    const result = plugin.configSchema.safeParse(pluginEntry.config);
    if (!result.success) {
      throw new ConfigValidationError(
        `Plugin ${pluginId} config validation failed`,
        result.error
      );
    }
  }
}
  • Add test cases to ensure the updated validation works correctly, such as:
describe("plugin config delegation", () => {
  it("accepts config fields declared in plugin configSchema", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              embedding: { apiKey: "test", baseURL: "https://example.com" },
              dbPath: "~/.openclaw/memory",
              autoCapture: true
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).not.toThrow();
  });

  it("rejects config fields that fail plugin schema validation", () => {
    const config = {
      plugins: {
        entries: {
          "memory-lancedb-pro": {
            enabled: true,
            config: {
              invalidField: "should fail"
            }
          }
        }
      }
    };

    expect(() => validateConfig(config)).toThrow(/invalidField/);
  });
});

Verification

To verify the fix, restart the gateway with the updated configuration and check that the memory plugins are loaded correctly. You can also test the validation by intentionally introducing invalid config fields and checking that the gateway throws an error.

Extra Tips

  • Make sure to update the loadedPlugins map to include the configSchema for each plugin.
  • Consider adding additional logging or debugging statements to help diagnose any issues that may arise during validation.
  • Review the related issues (#39535, #43551, #43769) to ensure that the fix addresses all affected plugins and use cases.

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