openclaw - ✅(Solved) Fix Plugin architecture: register() called multiple times causes closure variables not shared (affects @mem0/openclaw-mem0) [2 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#77822Fetched 2026-05-06 06:20:49
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
2
Author
Timeline (top)
cross-referenced ×2commented ×1

Root Cause

Root cause: When before_prompt_build hook sets currentSessionId in Instance A, the memory_add tool reads from Instance B — always undefined.

Fix Action

Fix / Workaround

Our fix: We added a module-level _globalSessionIdMap to share state across instances. Patch repo: https://github.com/wanmeime/openclaw-mem0-fix

PR fix notes

PR #78075: fix: preserve plugin hook and tool closure state

Description (problem / solution / changelog)

Summary

Fixes plugin tool resolution so cached descriptor wrappers do not bypass an already-live plugin registry that owns both hooks and tools for the same plugin. That keeps hook handlers and tool factories on the same register() closure when a plugin uses closure state across before_prompt_build and a tool like memory_add.

Changes

  • Detect active/pinned-channel registries that already contain a plugin's tools and hooks.
  • Skip cached descriptor wrappers for those stateful hook+tool plugins, forcing the normal live-registry materialization path.
  • Preserve descriptor caching for plain tool-only plugins and cold/no-live-registry paths.
  • Add regression coverage for a warmed descriptor cache being bypassed when a live hook+tool registry is available.

Testing

  • PATH="/tmp/openclaw-pnpm-shim:$PATH" pnpm vitest run src/plugins/tools.optional.test.ts — passed, 59 tests.
  • git diff --check — passed.
  • PATH="/tmp/openclaw-pnpm-shim:$PATH" node scripts/check-changed.mjs — all gates passed through final pairing-account guard; process was SIGKILLed at final exit on this host. Standalone PATH="/tmp/openclaw-pnpm-shim:$PATH" node scripts/check-pairing-account-scope.mjs passed.

Fixes #77822

Changed files

  • src/plugins/tools.optional.test.ts (modified, +64/-0)
  • src/plugins/tools.ts (modified, +28/-0)

PR #78114: Fix plugin shared state across repeated register calls

Description (problem / solution / changelog)

Fixes #77822.

Summary

  • add a plugin-id-scoped process-local shared state store
  • expose it as api.getSharedState() so repeated register(api) instances can coordinate explicitly
  • add a regression test covering state shared across repeated register calls

Verification

  • PATH="/tmp/openclaw-pnpm-shim:$PATH" ./node_modules/.bin/vitest run --config /tmp/vitest-issue-77822.config.ts (182 tests passed)
  • git diff --check
  • PATH="/tmp/openclaw-pnpm-shim:$PATH" node scripts/check-changed.mjs

Changed files

  • src/plugin-sdk/plugin-test-api.ts (modified, +1/-0)
  • src/plugins/api-builder.ts (modified, +3/-0)
  • src/plugins/loader.test.ts (modified, +41/-0)
  • src/plugins/registry.ts (modified, +2/-0)
  • src/plugins/shared-state.ts (added, +27/-0)
  • src/plugins/types.ts (modified, +8/-0)
RAW_BUFFERClick to expand / collapse

In OpenClaw 5.3+, plugins' register() function is called multiple times per conversation, which creates separate closures for each call. This causes module-level variables (like currentSessionId) to not be shared across instances.

Impact on @mem0/openclaw-mem0 plugin (v1.0.11):

  1. Agent memory isolation broken: user_id not concatenated with :agent:<agent_id> suffix
  2. run_id missing: Always None, can't filter memories by session
  3. autoCapture broken: Memories not auto-saved after conversations

Root cause: When before_prompt_build hook sets currentSessionId in Instance A, the memory_add tool reads from Instance B — always undefined.

Our fix: We added a module-level _globalSessionIdMap to share state across instances. Patch repo: https://github.com/wanmeime/openclaw-mem0-fix

Suggestion: Perhaps the plugin architecture could provide a shared state mechanism or ensure register() is only called once per session?

Thanks!

extent analysis

TL;DR

Implement a shared state mechanism or ensure the register() function is called only once per session to fix the issue with module-level variables not being shared across instances.

Guidance

  • Review the plugin architecture to determine the best approach for sharing state across instances, such as using a global map like _globalSessionIdMap.
  • Verify that the register() function is being called multiple times per conversation and identify the root cause of this behavior.
  • Consider implementing a singleton pattern or a caching mechanism to ensure that the register() function is only called once per session.
  • Evaluate the patch provided in the openclaw-mem0-fix repository to understand the proposed solution and determine if it can be applied to your use case.

Example

No code example is provided as the issue does not require a specific code snippet to illustrate the solution.

Notes

The provided patch repository (openclaw-mem0-fix) may not be applicable to all use cases, and the solution may need to be adapted to fit specific requirements.

Recommendation

Apply a workaround by implementing a shared state mechanism, such as a global map, to ensure that module-level variables are shared across instances. This approach allows for a more flexible and adaptable solution that can be tailored to specific 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

openclaw - ✅(Solved) Fix Plugin architecture: register() called multiple times causes closure variables not shared (affects @mem0/openclaw-mem0) [2 pull requests, 1 comments, 2 participants]