openclaw - ✅(Solved) Fix active-memory + memory-core dont compose: lightweight sub-agent bootstrap excludes memory-kind plugin tools, allowlist resolves to empty, placeholder turn lands in transcript [1 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#74572Fetched 2026-04-30 06:22:54
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Timeline (top)
commented ×1cross-referenced ×1

Error Message

bootstrapContextMode: "lightweight" appears to exclude tools registered by sibling plugins (memory-core in this case), so the runtime tool allowlist filters from an empty set → the error above. Both plugins ship in the bundled extensions directory and are documented to compose, but they don't out of the box.

Root Cause

Apparent root cause

extensions/active-memory/index.js:933 configures the embedded sub-agent with both:

Fix Action

Workaround

Disabling active-memory (plugins.entries.active-memory.enabled: false) stops the placeholder. hindsight-openclaw's autoRecall continues to inject context, so the loss is the bounded summarizer pre-step only. Not a fix — just a way to stop the visible noise.

PR fix notes

PR #74592: fix(active-memory): expose memory tools to recall runs

Description (problem / solution / changelog)

Summary

  • Problem: Active Memory lightweight embedded recall runs can allowlist Memory Core tools before those runtime plugin tools are materialized, collapsing the callable tool set.
  • Why it matters: memory_search and memory_get should remain callable when Memory Core is installed and Active Memory scopes the embedded run to memory tools.
  • What changed: runtime toolsAllow now contributes to generic plugin tool materialization, and Active Memory opts into gateway subagent binding for the embedded recall run.
  • What did NOT change (scope boundary): no plugin-specific tool IDs were hardcoded in core behavior, and no public SDK surface or memory storage behavior changed.

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 #74572
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: embedded runs applied the final runtime tool filter after creating the tool set, but the runtime toolsAllow was not also used to materialize matching plugin tools before that final filter.
  • Missing detection / guardrail: no focused test covered a lightweight embedded run that allowlists plugin-provided memory tools.
  • Contributing context (if known): Active Memory uses a narrow memory tool allowlist for recall runs while Memory Core registers memory_search and memory_get as plugin tools.

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: extensions/active-memory/index.test.ts, src/agents/pi-embedded-runner/run/attempt.test.ts, src/agents/pi-tools.create-openclaw-coding-tools.test.ts
  • Scenario the test should lock in: Active Memory recall runs pass gateway subagent binding, embedded attempt context carries runtime allowlists, and runtime allowlists contribute to plugin tool materialization.
  • Why this is the smallest reliable guardrail: it tests the generic tool composition seams without requiring a full gateway session.
  • Existing test that already covers this (if any): src/plugins/tools.optional.test.ts covers optional plugin tools and gateway-bindable registry behavior.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Active Memory recall runs can now call Memory Core plugin tools when Memory Core is installed and those tools are explicitly allowlisted for the embedded run.

Diagram (if applicable)

Before:
Active Memory recall -> toolsAllow(memory_*) -> plugin tools not materialized -> final filter can leave no callable memory tools

After:
Active Memory recall -> toolsAllow(memory_*) -> materialize matching plugin tools -> final filter keeps callable Memory Core tools

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) Yes
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: embedded runs can materialize only plugin tools already included in the explicit runtime allowlist and gateway-bindable registry; the final allowlist filter still applies.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node.js v24.14.0, pnpm 10.33.0
  • Model/provider: N/A
  • Integration/channel (if any): Active Memory + Memory Core
  • Relevant config (redacted): N/A

Steps

  1. Install Memory Core and Active Memory.
  2. Trigger an Active Memory embedded recall run with bootstrapContextMode: "lightweight" and toolsAllow: ["memory_recall", "memory_search", "memory_get"].
  3. Verify Memory Core plugin tools are materialized before the final embedded tool allowlist filter.

Expected

  • memory_search and memory_get remain callable when registered by Memory Core and explicitly allowlisted by the embedded run.

Actual

  • Before this change, the runtime allowlist could resolve to no callable tools because matching plugin tools were not materialized before final filtering.

Evidence

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

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • pnpm test extensions/active-memory/index.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts src/plugins/tools.optional.test.ts src/agents/pi-tools.create-openclaw-coding-tools.test.ts
    • pnpm exec oxfmt --check --threads=1 extensions/active-memory/index.ts extensions/active-memory/index.test.ts src/agents/pi-embedded-runner/run/attempt.tool-run-context.ts src/agents/pi-embedded-runner/run/attempt.test.ts src/agents/pi-tools.ts src/agents/pi-tools.create-openclaw-coding-tools.test.ts src/agents/test-helpers/fast-openclaw-tools.ts CHANGELOG.md
    • git diff --check
    • codex review --base origin/main
  • Edge cases checked:
    • runtime allowlist propagation when toolsAllow is present
    • generic plugin tool materialization without hardcoded memory plugin IDs
    • Active Memory preserves lightweight bootstrap and narrow memory tool allowlist
  • What you did not verify:
    • pnpm check:changed currently fails in extension test typecheck on a pre-existing duplicate-property error in extensions/memory-wiki/src/claim-health.test.ts that is present on origin/main.

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: broader plugin tool materialization than intended for embedded runs.
    • Mitigation: only explicit runtime allowlist entries are added to the existing plugin tool allowlist composition, and the final tool filter still applies.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/active-memory/index.test.ts (modified, +1/-0)
  • extensions/active-memory/index.ts (modified, +1/-0)
  • src/agents/pi-embedded-runner/run/attempt.test.ts (modified, +19/-0)
  • src/agents/pi-embedded-runner/run/attempt.tool-run-context.ts (modified, +3/-0)
  • src/agents/pi-tools.create-openclaw-coding-tools.test.ts (modified, +18/-1)
  • src/agents/pi-tools.ts (modified, +3/-0)
  • src/agents/test-helpers/fast-openclaw-tools.ts (modified, +3/-1)

Code Example

[agent/embedded] [tools] No callable tools remain after resolving explicit tool allowlist (runtime toolsAllow: memory_search, memory_get); no registered tools matched. Fix the allowlist or enable the plugin that registers the requested tool.

---

[agent/embedded] embedded run failover decision: ... stage=prompt decision=surface_error reason=none ... rawError=No callable tools remain after resolving explicit tool allowlist (runtime toolsAllow: memory_search, memory_get); no registered tools matched.

---

toolsAllow: ["memory_search", "memory_get"],
bootstrapContextMode: "lightweight",
RAW_BUFFERClick to expand / collapse

Environment

  • openclaw 2026.4.26
  • Plugins enabled: active-memory, memory-core, hindsight-openclaw
  • Provider tested: deepseek/deepseek-chat (provider-independent — fails before reaching the model)

Repro

  1. Enable both active-memory and memory-core in plugins.entries. No further config beyond enabled: true; defaults for both.
  2. Restart gateway. Confirm memory-core loads (openclaw memory --help works; the plugin registers memory_search and memory_get per extensions/memory-core/index.js:789-805).
  3. Send any user turn that triggers active-memory's pre-summarizer.

Expected

Active-memory's embedded sub-agent runs against the configured provider with tools memory_search + memory_get available.

Actual

Sub-agent fails with:

[agent/embedded] [tools] No callable tools remain after resolving explicit tool allowlist (runtime toolsAllow: memory_search, memory_get); no registered tools matched. Fix the allowlist or enable the plugin that registers the requested tool.

Followed by:

[agent/embedded] embedded run failover decision: ... stage=prompt decision=surface_error reason=none ... rawError=No callable tools remain after resolving explicit tool allowlist (runtime toolsAllow: memory_search, memory_get); no registered tools matched.

The user-visible chat then shows [assistant turn failed before producing content] (from STREAM_ERROR_FALLBACK_TEXT in compaction-successor-transcript) as a placeholder turn, polluting the saved transcript permanently. Hindsight's auto-recall later quotes that placeholder back as "Prior context" on every subsequent turn.

Apparent root cause

extensions/active-memory/index.js:933 configures the embedded sub-agent with both:

toolsAllow: ["memory_search", "memory_get"],
bootstrapContextMode: "lightweight",

bootstrapContextMode: "lightweight" appears to exclude tools registered by sibling plugins (memory-core in this case), so the runtime tool allowlist filters from an empty set → the error above. Both plugins ship in the bundled extensions directory and are documented to compose, but they don't out of the box.

Suggested fixes (any one would resolve)

  • active-memory uses a bootstrap mode that includes memory-kind plugin tools when its allowlist references them.
  • memory-core opts into lightweight bootstrap visibility.
  • active-memory pre-checks tool availability and skips/logs-warning instead of emitting a placeholder turn that lands in the persisted transcript.

Workaround

Disabling active-memory (plugins.entries.active-memory.enabled: false) stops the placeholder. hindsight-openclaw's autoRecall continues to inject context, so the loss is the bounded summarizer pre-step only. Not a fix — just a way to stop the visible noise.

extent analysis

TL;DR

The most likely fix is to modify the active-memory plugin to use a bootstrap mode that includes tools registered by sibling plugins, such as memory-core, or to modify memory-core to opt into lightweight bootstrap visibility.

Guidance

  • Verify that the memory-core plugin is correctly registering the memory_search and memory_get tools by checking the extensions/memory-core/index.js file and the output of openclaw memory --help.
  • Consider modifying the active-memory plugin to pre-check tool availability and skip or log a warning instead of emitting a placeholder turn that lands in the persisted transcript.
  • Investigate the possibility of modifying memory-core to opt into lightweight bootstrap visibility, allowing its tools to be included in the active-memory plugin's allowlist.
  • Test the workaround of disabling active-memory to stop the visible noise, but note that this will disable the bounded summarizer pre-step.

Example

No code snippet is provided as the issue is more related to plugin configuration and interaction.

Notes

The issue seems to be related to the interaction between the active-memory and memory-core plugins, and the bootstrap mode used by active-memory. The suggested fixes and workaround are based on the information provided in the issue, but further investigation and testing may be necessary to determine the best solution.

Recommendation

Apply the workaround of disabling active-memory to stop the visible noise, as this is a temporary solution that can mitigate the issue while a more permanent fix is developed. However, it's recommended to investigate and implement one of the suggested fixes to fully resolve the issue and restore the functionality of the active-memory plugin.

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