openclaw - 💡(How to fix) Fix Document Codex app-server report-mode handling of plugin requireApproval

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…

OpenClaw plugin before_tool_call hooks can return requireApproval in the normal OpenClaw tool path. In that path, OpenClaw opens a plugin approval request through plugin.approval.request and waits for a decision through plugin.approval.waitDecision.

Under the native Codex app-server hook relay, the same hook-level requireApproval does not open an OpenClaw plugin approval prompt/card. When the raw Codex payload includes openclaw_approval_mode: "report", OpenClaw converts the approval requirement into a denied PreToolUse response with permissionDecision: "deny".

This appears to be intentional, or at least currently enforced by tests, but it is easy for plugin authors to miss. A plugin that expects native OpenClaw/Discord approval buttons may only block the command and never surface an interactive approval path.

Root Cause

OpenClaw plugin before_tool_call hooks can return requireApproval in the normal OpenClaw tool path. In that path, OpenClaw opens a plugin approval request through plugin.approval.request and waits for a decision through plugin.approval.waitDecision.

Under the native Codex app-server hook relay, the same hook-level requireApproval does not open an OpenClaw plugin approval prompt/card. When the raw Codex payload includes openclaw_approval_mode: "report", OpenClaw converts the approval requirement into a denied PreToolUse response with permissionDecision: "deny".

This appears to be intentional, or at least currently enforced by tests, but it is easy for plugin authors to miss. A plugin that expects native OpenClaw/Discord approval buttons may only block the command and never surface an interactive approval path.

Fix Action

Fix / Workaround

The behavior is safe, but surprising. It can lead plugin authors to design a safety gate that depends on a native approval card that will never appear on this path. The practical workaround is to avoid returning requireApproval for Codex-native report-mode hooks and instead block with a clear retry/out-of-band approval flow.

I have a small local docs patch available that adds this clarification to docs/tools/acp-agents.md if that is the preferred direction.

Code Example

return {
  requireApproval: {
    title: "Needs approval",
    description: "native command needs approval"
  }
};
RAW_BUFFERClick to expand / collapse

Summary

OpenClaw plugin before_tool_call hooks can return requireApproval in the normal OpenClaw tool path. In that path, OpenClaw opens a plugin approval request through plugin.approval.request and waits for a decision through plugin.approval.waitDecision.

Under the native Codex app-server hook relay, the same hook-level requireApproval does not open an OpenClaw plugin approval prompt/card. When the raw Codex payload includes openclaw_approval_mode: "report", OpenClaw converts the approval requirement into a denied PreToolUse response with permissionDecision: "deny".

This appears to be intentional, or at least currently enforced by tests, but it is easy for plugin authors to miss. A plugin that expects native OpenClaw/Discord approval buttons may only block the command and never surface an interactive approval path.

Current behavior

For Codex-native app-server PreToolUse events in report mode:

  1. A plugin before_tool_call hook returns requireApproval.
  2. No OpenClaw plugin approval prompt is opened.
  3. The Codex hook response denies the tool call using the approval title/description as the deny reason.

Expected / requested clarification

At minimum, please document this boundary clearly for plugin authors:

  • hook-level plugin requireApproval in Codex app-server PreToolUse report mode is reported back to Codex as deny/block, not surfaced as an interactive OpenClaw approval prompt;
  • plugins that need approval on this path should return block with explicit user instructions, or use an out-of-band durable approval workflow;
  • Codex PermissionRequest routing through OpenClaw approvals is separate from plugin hook requireApproval on native tool events.

If interactive plugin approvals are intended to work for Codex-native tools, then this should probably be tracked as a bug/feature request instead: OpenClaw would need a first-class bridge that can safely suspend the native tool call, preserve rewritten params, and avoid Codex continuing with the original params.

Code pointers from local inspection

Local version inspected: c81ce46562 (2026.5.20).

  • src/agents/pi-tools.before-tool-call.ts has the normal plugin approval path in requestPluginToolApproval(...).
  • src/agents/pi-tools.before-tool-call.ts special-cases args.approvalMode === "report" for both trusted policy requireApproval and hook requireApproval, returning a blocked/failure outcome instead of requesting plugin approval.
  • src/agents/harness/native-hook-relay.ts passes approvalMode: "report" when the native payload has openclaw_approval_mode: "report".
  • src/agents/harness/native-hook-relay.ts renders blocked outcomes as Codex PreToolUse deny responses.
  • src/agents/harness/native-hook-relay.test.ts has a test named reports synthetic app-server PreToolUse approval requirements without opening plugin approvals, and it asserts a permissionDecision: "deny" response.

Reproduction shape

  1. Enable an OpenClaw plugin with a before_tool_call hook.
  2. Have the hook return:
return {
  requireApproval: {
    title: "Needs approval",
    description: "native command needs approval"
  }
};
  1. Trigger a Codex-native tool call through the app-server hook relay where the raw payload uses openclaw_approval_mode: "report".
  2. Observe that no OpenClaw plugin approval prompt/card is opened; Codex receives a denied PreToolUse response using the approval description as the deny reason.

Impact

The behavior is safe, but surprising. It can lead plugin authors to design a safety gate that depends on a native approval card that will never appear on this path. The practical workaround is to avoid returning requireApproval for Codex-native report-mode hooks and instead block with a clear retry/out-of-band approval flow.

Possible fixes

  1. Documentation-only: clarify this in the native Codex routing docs.
  2. Diagnostics: emit a warning when a plugin returns requireApproval while approvalMode === "report".
  3. Feature: add a first-class Codex-native approval bridge, if the runtime can safely suspend/resume native tool calls and preserve rewritten params.

I have a small local docs patch available that adds this clarification to docs/tools/acp-agents.md if that is the preferred direction.

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 - 💡(How to fix) Fix Document Codex app-server report-mode handling of plugin requireApproval