openclaw - 💡(How to fix) Fix codex: explicit toolsAllow lists strip native read/write/edit/exec instead of enabling them

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…

In @openclaw/[email protected], isolated agent sessions that specify an explicit toolsAllow array (e.g. ["read","write","edit","memory_search"]) end up with only the non-codex-owned MCP tools that match the allowlist. The native codex tools (read, write, edit, exec, apply_patch, process, update_plan) are silently unavailable. The agent reports "no write tool available" while the run completes with status: ok.

Replacing toolsAllow with ["*"] (or omitting the field) makes the native tools available again, but it forfeits all per-cron tool restriction.

Error Message

Secondary suggestion: when an explicit toolsAllow requests a native-owned tool but the native surface is disabled (e.g. sandbox refuses), the run should warn/fail loudly instead of returning ok.

Root Cause

dist/dynamic-tools-Bq717oJR.js:5–17 excludes native codex tools from the dynamic tool surface:

const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
  "read", "write", "edit", "apply_patch", "exec", "process",
  "update_plan", "tool_call", "tool_describe", "tool_search", "tool_search_code"
];

…and dist/run-attempt-CT1N__qp.js:6993–7003 only enables the native tool surface when toolsAllow is undefined or contains a "*" wildcard:

function shouldEnableCodexAppServerNativeToolSurface(params, sandbox, options = {}) {
  if (isCodexMemoryFlushRun(params)) return false;
  if (isCodexNativeExecutionBlockedByNodeExecHost(params, {})) return false;
  const toolsAllow = includeForcedCodexDynamicToolAllow(params.toolsAllow, params);
  if (toolsAllow === void 0) return canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
  return hasWildcardCodexToolsAllow(toolsAllow) && canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
}

So an explicit list containing "read"/"write"/"edit" triggers neither path. The dynamic surface has already excluded those names as native-owned, and the native surface refuses to enable without wildcard. Result: silent loss of the requested tools.

Fix Action

Fix / Workaround

In @openclaw/[email protected], isolated agent sessions that specify an explicit toolsAllow array (e.g. ["read","write","edit","memory_search"]) end up with only the non-codex-owned MCP tools that match the allowlist. The native codex tools (read, write, edit, exec, apply_patch, process, update_plan) are silently unavailable. The agent reports "no write tool available" while the run completes with status: ok.

const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
  "read", "write", "edit", "apply_patch", "exec", "process",
  "update_plan", "tool_call", "tool_describe", "tool_search", "tool_search_code"
];

Code Example

{
     "kind": "agentTurn",
     "model": "openai/gpt-5.5",
     "toolsAllow": ["read", "write", "edit", "memory_search", "memory_get", "session_status"],
     "message": "List your available tools, then create /tmp/codex-toolsallow-test.txt with the word OK."
   }

---

const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
  "read", "write", "edit", "apply_patch", "exec", "process",
  "update_plan", "tool_call", "tool_describe", "tool_search", "tool_search_code"
];

---

function shouldEnableCodexAppServerNativeToolSurface(params, sandbox, options = {}) {
  if (isCodexMemoryFlushRun(params)) return false;
  if (isCodexNativeExecutionBlockedByNodeExecHost(params, {})) return false;
  const toolsAllow = includeForcedCodexDynamicToolAllow(params.toolsAllow, params);
  if (toolsAllow === void 0) return canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
  return hasWildcardCodexToolsAllow(toolsAllow) && canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
}

---

const hasNativeRequest = toolsAllow.some(name =>
  CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES.includes(normalizeCodexDynamicToolName(name))
);
return (hasWildcardCodexToolsAllow(toolsAllow) || hasNativeRequest)
  && canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
RAW_BUFFERClick to expand / collapse

Summary

In @openclaw/[email protected], isolated agent sessions that specify an explicit toolsAllow array (e.g. ["read","write","edit","memory_search"]) end up with only the non-codex-owned MCP tools that match the allowlist. The native codex tools (read, write, edit, exec, apply_patch, process, update_plan) are silently unavailable. The agent reports "no write tool available" while the run completes with status: ok.

Replacing toolsAllow with ["*"] (or omitting the field) makes the native tools available again, but it forfeits all per-cron tool restriction.

Repro

  1. Create an isolated cron with a payload like:
    {
      "kind": "agentTurn",
      "model": "openai/gpt-5.5",
      "toolsAllow": ["read", "write", "edit", "memory_search", "memory_get", "session_status"],
      "message": "List your available tools, then create /tmp/codex-toolsallow-test.txt with the word OK."
    }
  2. Trigger it. Observed: the agent only has memory_search, memory_get, session_status; reports inability to write the file. Run completes ok.

Root cause

dist/dynamic-tools-Bq717oJR.js:5–17 excludes native codex tools from the dynamic tool surface:

const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
  "read", "write", "edit", "apply_patch", "exec", "process",
  "update_plan", "tool_call", "tool_describe", "tool_search", "tool_search_code"
];

…and dist/run-attempt-CT1N__qp.js:6993–7003 only enables the native tool surface when toolsAllow is undefined or contains a "*" wildcard:

function shouldEnableCodexAppServerNativeToolSurface(params, sandbox, options = {}) {
  if (isCodexMemoryFlushRun(params)) return false;
  if (isCodexNativeExecutionBlockedByNodeExecHost(params, {})) return false;
  const toolsAllow = includeForcedCodexDynamicToolAllow(params.toolsAllow, params);
  if (toolsAllow === void 0) return canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
  return hasWildcardCodexToolsAllow(toolsAllow) && canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);
}

So an explicit list containing "read"/"write"/"edit" triggers neither path. The dynamic surface has already excluded those names as native-owned, and the native surface refuses to enable without wildcard. Result: silent loss of the requested tools.

Impact

Every nightly memory-consolidation cron in our setup with explicit toolsAllow has been completing successfully but writing nothing for at least several days — each one returns "FIXED: none, no write tool available" while lastRunStatus: ok. Failure is invisible to the cron-status surface.

Proposed fix

shouldEnableCodexAppServerNativeToolSurface should also enable the native surface when toolsAllow contains any native-owned name. Something like:

const hasNativeRequest = toolsAllow.some(name =>
  CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES.includes(normalizeCodexDynamicToolName(name))
);
return (hasWildcardCodexToolsAllow(toolsAllow) || hasNativeRequest)
  && canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options);

…with the dynamic-tool filter additionally accepting native-tool names in the allowlist as "allow this native tool" rather than dropping it.

Secondary suggestion: when an explicit toolsAllow requests a native-owned tool but the native surface is disabled (e.g. sandbox refuses), the run should warn/fail loudly instead of returning ok.

Environment

  • openclaw: 2026.5.24-beta.2
  • @openclaw/codex: 2026.5.24-beta.2
  • macOS 25.5.0 / arm64
  • node v26.0.0

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