Skip to content

Codex harness: "native hook relay unavailable" — bridge record written but every tool fail-closes (2026.6.11, isolated multi-agent gateway) #98650

Description

@609NFT

Summary

On a self-hosted Gateway running multiple isolated agents, every Codex-harness tool call fail-closes with PreToolUse hook: Native hook relay unavailable, making codex agents completely unable to read/write/exec. The Anthropic/standard harness (in-process hooks) on the same gateway works fine.

This is not #73723 (the duplicate-module registry bug fixed by #73950): that fix is present in 2026.6.11 and does not apply here — the codex plugin's node_modules/openclaw is a symlink to the single host core copy (one module instance), and the Symbol.for("openclaw.nativeHookRelay.state") shared state is in place. Ours is a distinct "bridge server address unavailable" failure.

Environment

  • openclaw core: 2026.6.11
  • @openclaw/codex: 2026.6.11 (version-matched to core)
  • OS: Linux x86_64
  • Route: codex/gpt-5.3-codex via codex_oauth (ChatGPT) BYOK, per-agent auth in the sqlite auth store
  • Setup: one Gateway hosting many isolated agents (agents.list), OPENCLAW_STATE_DIR per profile

Repro

  1. Provision a codex-model agent on a Gateway with hooks.enabled: true.
  2. Drive a turn that runs a shell tool, e.g. openclaw agent --agent <id> -m "run: head -n 1 index.html".
  3. Codex returns: Command blocked by PreToolUse hook: Native hook relay unavailable. Codex app-server stderr: ERROR codex_core::tools::router: error=Command blocked by PreToolUse hook: Native hook relay unavailable.

Gateway logs per turn: [harness/native-hook-relay] native hook relay bridge server address unavailable.

Neither a fresh session (/new) nor a Gateway restart clears it — it is 100% reproducible.

Ruled out (during a long investigation)

  • Approval policy — set OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY=never (codex confirms approval_policy: never); still blocked.
  • Codex sandboxsandbox_policy: { type: "danger-full-access" }, network enabled; still blocked. Not a sandbox restriction.
  • Network namespace — Gateway, codex app-server, and the commands it spawns share the host net namespace; 127.0.0.1 loopback is reachable from the sandboxed command.
  • The bridge record IS written: ${TMPDIR}/openclaw-native-hook-relays-${uid}/<key>.json appears with a valid { hostname: "127.0.0.1", port, token, expiresAtMs }. So registration/listen succeeds — yet codex still reports the relay unavailable when invoking it.

Possible lead

In src/agents/harness/native-hook-relay.ts, registerNativeHookRelayBridge calls writeNativeHookRelayBridgeRecordForRegistration twice:

server.listen(0, "127.0.0.1", () => {
  if (relayBridges.get(registration.relayId) !== bridge) return;
  writeNativeHookRelayBridgeRecordForRegistration(registration, bridge); // async: address valid
});
if (relayBridges.get(registration.relayId) === bridge) {
  writeNativeHookRelayBridgeRecordForRegistration(registration, bridge); // sync: right after listen()
}

The synchronous call runs before listen() finishes binding, so server.address() is null → this is the source of the bridge server address unavailable log. The async callback still writes the record, so this looks benign — but flagging it in case a consumer reads the bridge record in the window before the async write, or the intended eager-write is load-bearing for the codex app-server's first tool call after registration.

Impact

Codex / codex_oauth BYOK agents are 100% unusable on the gateway (every tool blocked). The in-process (Anthropic/OpenAI) harness is unaffected. Current workaround is patching the codex harness to run without the native hook relay (fail-open), which loses the tool-approval bridge for codex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions