openclaw - ✅(Solved) Fix [Bug]: Plugin config validator runs on undefined config during CLI preflight/subcommand paths, producing false-positive 'invalid config' errors [1 pull requests, 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#70658Fetched 2026-04-24 05:55:06
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2

The OpenClaw plugin loader calls validatePluginConfig with value: undefined during preflight / subcommand code paths, producing non-actionable "invalid config" errors for plugins whose config is valid and working at runtime. The plugin later activates successfully via the normal gateway path with the real config, so these errors are purely preflight noise — but they spam gateway.err.log and stderr on every CLI invocation, drowning real errors.

Error Message

  1. Run any CLI subcommand (e.g. openclaw sessions cleanup, openclaw cron list) — the same error is printed to stderr even though the command completes successfully. The plugin is then loaded again via the real gateway activation path with the correct config and works fine. So the validation that fires the error is not the one gating actual activation — it's a preflight / subcommand tick where the config hasn't been materialized yet.
  • Plugin-side tracking (error-message clarity + tolerance for undefined value): CortexReach/memory-lancedb-pro#685. Plugin collaborator (@AliceLJY) has confirmed the runtime embedding requirement is intentional and redirected the root-cause fix here.

Root Cause

No validation errors for plugins whose config is valid and is successfully used at activation. Preflight / subcommand paths should not surface ajv failures from a config value that is undefined only because that code path hasn't loaded it.

Fix Action

Fixed

PR fix notes

PR #70811: fix(plugins): defer undefined config validation in snapshot loads (Fixes #70658)

Description (problem / solution / changelog)

Summary

  • Problem: non-activating plugin loads were validating entry?.config even when that preflight or CLI path had not materialized plugin config yet, which produced false-positive invalid config errors for otherwise healthy plugins.
  • Why it matters: the error shows up in gateway.err.log and on CLI subcommands, which makes real plugin failures harder to spot and sends users debugging valid config.
  • What changed: non-activating loads now skip schema validation when plugin config is still undefined, while real activation paths and non-activating loads with explicit config still validate as before. Added focused regression coverage for manifest-only snapshot loads and CLI metadata capture.
  • What did NOT change (scope boundary): this does not relax validation for real plugin activation, change plugin config schemas, or alter plugin runtime behavior once config is actually present.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #70658
  • Related #64946
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the plugin loader always ran validatePluginConfig before checking whether the current load was a real activation or a metadata/preflight path. In those non-activating paths, some plugins can be discovered before plugins.entries.<id>.config exists, so AJV validated undefined as {} and reported missing required root fields.
  • Missing detection / guardrail: there was no branch that treated undefined config as "not materialized yet" for snapshot and CLI metadata loads.
  • Contributing context (if known): the same validator is reused across activation, snapshot, and CLI metadata paths, so the false positive only showed up when a non-activating path reached a strict plugin schema first.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/plugins/loader.test.ts, src/plugins/loader.cli-metadata.test.ts
  • Scenario the test should lock in: non-activating snapshot and CLI metadata loads should not fail plugin discovery when a strict config schema exists but plugin config is still undefined.
  • Why this is the smallest reliable guardrail: the regression happens entirely inside loader branching, so focused loader tests exercise the real decision point without needing gateway or CLI end-to-end setup.
  • Existing test that already covers this (if any): passes validated plugin config into non-activating CLI metadata loads already covers the explicit-config side of this branch.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

CLI preflight and metadata paths stop emitting false invalid config errors for plugins whose real runtime config is valid but has not been materialized in that path yet.

Diagram (if applicable)

Before:
[snapshot or CLI metadata load] -> [config is undefined] -> [AJV validates {}] -> [false invalid config error]

After:
[snapshot or CLI metadata load] -> [config is undefined] -> [defer validation] -> [plugin metadata loads cleanly]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node.js repo test runner
  • Model/provider: N/A
  • Integration/channel (if any): external plugins with strict top-level configSchema.required
  • Relevant config (redacted): plugin allowed and discoverable, but non-activating load path does not provide plugins.entries.<id>.config

Steps

  1. Install or discover a plugin whose manifest has a strict top-level required config field.
  2. Trigger a non-activating plugin load path such as CLI metadata capture or a manifest-only snapshot while the plugin config for that path is still undefined.
  3. Observe loader behavior before and after this change.

Expected

  • Non-activating loads should defer validation until real config exists and should not emit a false invalid config error.

Actual

  • Before this change, the loader validated undefined as an empty object and reported missing required properties.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: ran node scripts/run-vitest.mjs run --config test/vitest/vitest.unit.config.ts src/plugins/loader.test.ts src/plugins/loader.cli-metadata.test.ts and confirmed the focused loader tests pass with the new regression coverage.
  • Edge cases checked: explicit-config non-activating validation is still covered by the existing CLI metadata test; real activation still keeps validation because the guard only skips undefined config on non-activating loads.
  • What you did not verify: I did not reproduce against a live external plugin package or run the full plugin test suite.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: a non-activating path could now tolerate an undefined config for a plugin that would still fail once actually activated.
    • Mitigation: real activation paths still validate, and non-activating paths continue validating whenever explicit config is present.

Changed files

  • src/plugins/loader.cli-metadata.test.ts (modified, +60/-0)
  • src/plugins/loader.test.ts (modified, +104/-0)
  • src/plugins/loader.ts (modified, +51/-20)

Code Example

[plugins] memory-lancedb-pro invalid config: embedding: must have required property 'embedding'

---

const validatedConfig = validatePluginConfig({
  schema: manifestRecord.configSchema,
  cacheKey: manifestRecord.schemaCacheKey,
  value: entry?.config,
});

---

if (entry?.config === undefined) {
  // defer: real activation path will validate with the real config
  return;
}
const validatedConfig = validatePluginConfig({ ... });
RAW_BUFFERClick to expand / collapse

Summary

The OpenClaw plugin loader calls validatePluginConfig with value: undefined during preflight / subcommand code paths, producing non-actionable "invalid config" errors for plugins whose config is valid and working at runtime. The plugin later activates successfully via the normal gateway path with the real config, so these errors are purely preflight noise — but they spam gateway.err.log and stderr on every CLI invocation, drowning real errors.

Version

  • OpenClaw: 2026.4.8 (commit 9ece252)
  • Node 22 (Homebrew), macOS (Mac mini), single-user local gateway

Reproduction

  1. Install any external plugin whose configSchema has a strict top-level required. Easiest concrete repro: [email protected] with a valid config block (see CortexReach/memory-lancedb-pro#685 for the exact block).

  2. Start the gateway: ~/.openclaw/bin/openclaw-gateway-wrapper.sh.

  3. tail -f ~/.openclaw/logs/gateway.err.log — repeated:

    [plugins] memory-lancedb-pro invalid config: embedding: must have required property 'embedding'
  4. Run any CLI subcommand (e.g. openclaw sessions cleanup, openclaw cron list) — the same error is printed to stderr even though the command completes successfully.

Expected

No validation errors for plugins whose config is valid and is successfully used at activation. Preflight / subcommand paths should not surface ajv failures from a config value that is undefined only because that code path hasn't loaded it.

Actual

The loader calls validatePluginConfig with entry?.config that is undefined in some preflight / subcommand code paths. From the published loader-CVkGO8jl.js in the bundled CLI:

const validatedConfig = validatePluginConfig({
  schema: manifestRecord.configSchema,
  cacheKey: manifestRecord.schemaCacheKey,
  value: entry?.config,
});

When entry resolves to undefined, value is undefined, AJV reports required: embedding missing at root, and the log formatter renders it as embedding: must have required property 'embedding' (self-referential — the missing key and the root path segment are both embedding).

The plugin is then loaded again via the real gateway activation path with the correct config and works fine. So the validation that fires the error is not the one gating actual activation — it's a preflight / subcommand tick where the config hasn't been materialized yet.

Impact

  • Not functionally broken: affected plugins load and work (hybrid retrieval for memory-lancedb-pro is normal).
  • Log spam: dozens of identical invalid config lines per gateway restart and on every CLI invocation. Drowns real errors in gateway.err.log.
  • Misleading wording: the self-referential embedding: must have required property 'embedding' misdirects debugging toward user config rather than loader behavior. Two independent users on the plugin side hit this and filed valid configs (CortexReach/memory-lancedb-pro#685, #651).

Suggested fix

Skip validatePluginConfig when entry?.config === undefined in preflight / subcommand-only contexts, and only validate when the plugin is actually being activated. Roughly:

if (entry?.config === undefined) {
  // defer: real activation path will validate with the real config
  return;
}
const validatedConfig = validatePluginConfig({ ... });

Or pass a context flag to the loader distinguishing preflight vs activation and validate only in the latter.

Related

  • Plugin-side tracking (error-message clarity + tolerance for undefined value): CortexReach/memory-lancedb-pro#685. Plugin collaborator (@AliceLJY) has confirmed the runtime embedding requirement is intentional and redirected the root-cause fix here.
  • Sibling report from another user on the same plugin, same family: CortexReach/memory-lancedb-pro#651.
  • #64946 is a sibling in the same "plugin config validator noise" family but a different root cause — two validators disagreeing on wrapped/unwrapped schema shape and firing every ~500ms on wrapped-config plugins. Worth linking because the fix pattern here (context-aware validation) may overlap, but they shouldn't be merged.

Happy to test a candidate fix.

extent analysis

TL;DR

Skip validatePluginConfig when entry?.config === undefined in preflight/subcommand contexts to prevent log spam and misleading errors.

Guidance

  • Identify preflight/subcommand code paths where entry?.config is undefined and skip validation in these cases.
  • Consider passing a context flag to the loader to distinguish between preflight and activation paths.
  • Review the loader-CVkGO8jl.js file to ensure the suggested fix is applied correctly.
  • Test the fix with the memory-lancedb-pro plugin to verify that log spam is reduced and errors are no longer misleading.

Example

if (entry?.config === undefined) {
  // defer: real activation path will validate with the real config
  return;
}
const validatedConfig = validatePluginConfig({
  schema: manifestRecord.configSchema,
  cacheKey: manifestRecord.schemaCacheKey,
  value: entry?.config,
});

Notes

The suggested fix assumes that the entry?.config value is only undefined in preflight/subcommand contexts and that the real activation path will validate the config correctly. If this assumption is incorrect, additional debugging may be necessary.

Recommendation

Apply the suggested fix by skipping validatePluginConfig when entry?.config === undefined in preflight/subcommand contexts. This should reduce log spam and prevent misleading errors.

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]: Plugin config validator runs on undefined config during CLI preflight/subcommand paths, producing false-positive 'invalid config' errors [1 pull requests, 1 participants]