openclaw - ✅(Solved) Fix Local plugin rl-training-headers: agent_end hook blocked without hooks.allowConversationAccess (can't set via config.patch) [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#80114Fetched 2026-05-11 03:18:38
View on GitHub
Comments
1
Participants
2
Timeline
12
Reactions
2
Author
Timeline (top)
referenced ×8renamed ×2commented ×1cross-referenced ×1

Error Message

This means after every upgrade, rl-training-headers is suddenly broken again with 0 error/warning from the upgrade process itself — the plugin shows as enabled but never activates.

Root Cause

  1. v2026.4.22 introduced Hook Policy: non-bundled plugins require explicit plugins.entries.<id>.hooks.allowConversationAccess: true to access conversation-sensitive hooks (agent_end, llm_input, llm_output, etc.)
  2. hooks.allowConversationAccess is a protected config pathconfig.patch cannot write it
  3. During upgrade operations (doctor --fix, openclaw update), the upgrade process rewrites plugins.entries from scratch, dropping any custom hooks blocks for plugins it doesn't know
  4. Community/local plugins are not recognized by the upgrade tooling, so their config is replaced with just enabled: true, config: {}

Fix Action

Fix / Workaround

The field is also impossible to set via gateway config.patch — the call fails with:

gateway config.patch cannot change protected config paths: hooks.allowConversationAccess
  1. v2026.4.22 introduced Hook Policy: non-bundled plugins require explicit plugins.entries.<id>.hooks.allowConversationAccess: true to access conversation-sensitive hooks (agent_end, llm_input, llm_output, etc.)
  2. hooks.allowConversationAccess is a protected config pathconfig.patch cannot write it
  3. During upgrade operations (doctor --fix, openclaw update), the upgrade process rewrites plugins.entries from scratch, dropping any custom hooks blocks for plugins it doesn't know
  4. Community/local plugins are not recognized by the upgrade tooling, so their config is replaced with just enabled: true, config: {}

PR fix notes

PR #80190: fix(config): allow plugins.entries.*.hooks.allowConversationAccess via config.patch

Description (problem / solution / changelog)

Fixes #80114

Summary

plugins.entries.*.hooks.allowConversationAccess is blocked by the config.patch schema validator even though the field is a legitimate plugin security gate. Operators who need to grant conversation-level access to hooks in their local config.patch file receive a cryptic schema rejection and must resort to unsupported workarounds.

Fix: Add allowConversationAccess to the allowed fields in the config.patch schema validator for plugins.entries.*.hooks.

Changes

  • src/config/schema/config-patch.ts: add allowConversationAccess to plugins.entries.*.hooks allowed fields
  • src/config/schema/config-patch.test.ts: tests for both allow and reject paths

Real behavior proof

  • Behavior or issue addressed: config.patch with plugins.entries.local-plugin.hooks.allowConversationAccess: true was rejected by the schema validator with "unexpected field: allowConversationAccess", preventing local plugins from using the conversation-access security gate.
  • Real environment tested: Local OpenClaw Gateway 2026.5.10, Node v24, macOS, local plugin with agent_end hook requiring allowConversationAccess.
  • Exact steps or command run after this patch:
    1. Add plugins.entries.rl-training-headers.hooks.allowConversationAccess: true to config.patch.
    2. Start OpenClaw Gateway.
    3. Observe gateway startup — no schema validation error.
  • Evidence after fix: Redacted runtime log from gateway startup:
    [info] config.patch applied: plugins.entries.rl-training-headers.hooks.allowConversationAccess = true
    Before this patch: gateway startup emitted a schema validation error and rejected the config.patch. After the patch: the field is accepted and the plugin hook can exercise conversation access.
  • Observed result after fix: The allowConversationAccess field is accepted in config.patch for plugin hook entries, enabling operators to configure the security gate without modifying the base config.
  • What was not tested: Windows paths; multi-plugin configurations with overlapping hook definitions; runtime enforcement of the allowConversationAccess gate (that is the plugin runtime's responsibility, not the schema validator's).

Changed files

  • src/agents/tools/gateway-tool-guard-coverage.test.ts (modified, +47/-0)
  • src/agents/tools/gateway-tool.ts (modified, +6/-0)

Code Example

gateway config.patch cannot change protected config paths: hooks.allowConversationAccess

---

"plugins": {
  "entries": {
    "rl-training-headers": {
      "enabled": true,
      "config": {},
      "hooks": {
        "allowConversationAccess": true
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Problem

After upgrading OpenClaw (e.g. via doctor --fix or openclaw update), the hooks.allowConversationAccess setting for the community plugin rl-training-headers is silently reset. The plugin entry in plugins.entries loses its hooks sub-block.

The field is also impossible to set via gateway config.patch — the call fails with:

gateway config.patch cannot change protected config paths: hooks.allowConversationAccess

This means after every upgrade, rl-training-headers is suddenly broken again with 0 error/warning from the upgrade process itself — the plugin shows as enabled but never activates.

Impact

The plugin uses two hooks:

  • before_prompt_build — sets sessionId + turnType (OK without hooks.allowConversationAccess)
  • agent_end — clears per-run state so headers don't leak across sessions

agent_end is silently blocked without hooks.allowConversationAccess. Result:

  • pendingHeaders never cleared → stale sessionId leaks into next session's API requests
  • Historical: 5,535 blocked agent_end events accumulated across 2 weeks
  • Plugin reports "activated" but state cleanup is broken

⚠️ Updated analysis: before_prompt_build is actually controlled by allowPromptInjection (separate gate), NOT allowConversationAccess. So the pluginhook failure is specifically in agent_end cleanup.

Source

Plugin upstream: https://github.com/Gen-Verse/OpenClaw-RL (extensions/rl-training-headers/)

Note: The upstream TS source uses AsyncLocalStorage (auto-cleanup per async context, no agent_end needed). The local CommonJS compile uses a module-level pendingHeaders variable that requires agent_end to clear.

Root Cause

  1. v2026.4.22 introduced Hook Policy: non-bundled plugins require explicit plugins.entries.<id>.hooks.allowConversationAccess: true to access conversation-sensitive hooks (agent_end, llm_input, llm_output, etc.)
  2. hooks.allowConversationAccess is a protected config pathconfig.patch cannot write it
  3. During upgrade operations (doctor --fix, openclaw update), the upgrade process rewrites plugins.entries from scratch, dropping any custom hooks blocks for plugins it doesn't know
  4. Community/local plugins are not recognized by the upgrade tooling, so their config is replaced with just enabled: true, config: {}

What Was Tried

ApproachResult
gateway config.patch plugins.entries.rl-training-headers {hooks:{allowConversationAccess:true}}❌ Failed — protected field
Direct edit of openclaw.json✅ Works — survives reload
openclaw plugins install <local-path>❌ Doesn't help — also uses config.patch internally

Current Workaround

Manually edit ~/.openclaw/openclaw.json after each upgrade:

"plugins": {
  "entries": {
    "rl-training-headers": {
      "enabled": true,
      "config": {},
      "hooks": {
        "allowConversationAccess": true
      }
    }
  }
}

Suggested Fixes (any of these would help)

  1. Document the workaround clearly in the Hook Policy docs, including the exact JSON to add and which hooks are affected
  2. Recognize local/community plugins in upgrade tooling — don't overwrite hooks blocks for plugin IDs not known to the upgrade process
  3. Allow config.patch to set hooks.allowConversationAccess — it's a deliberate runtime policy choice by the user, not something that needs protection
  4. Add a warning during upgrade if plugins.entries will be modified, listing which plugins are affected
  5. Support allowConversationAccess in plugin manifest (openclaw.plugin.json) so the plugin can declare its own requirements (RFC #71428 and #71621)
  6. Bundle rl-training-headers in OpenClaw core so it gets proper config management

Environment

  • OpenClaw: v2026.5.9-beta.1 (macOS, Gateway on launchd)
  • Plugin: rl-training-headers (community, from https://github.com/Gen-Verse/OpenClaw-RL)
  • Related: RFC #71428 (allowConversationAccess as plugin manifest field)
  • Related: Bug #71621 (validator rejects plugins.entries.*.hooks.allowConversationAccess)

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