openclaw - ✅(Solved) Fix infer model run fails before model call when tools.alsoAllow is set and modelRun disables tools [1 pull requests, 1 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#73024Fetched 2026-04-28 06:28:26
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

openclaw infer model run --local --model <id> --prompt <p> can abort before attempting any model call when ~/.openclaw/openclaw.json has a non-empty tools.alsoAllow.

The error is:

No callable tools remain after resolving explicit tool allowlist (tools.allow: *, lobster, llm-task)

This happens even though infer model run sets modelRun:true / disables tools intentionally. The target model and auth are valid. The same model succeeds when tools.alsoAllow is removed in a temp config.

Error Message

The error is: Because modelRun:true disables tools for this call shape, tool allowlist validation should not fail the model smoke. The command should attempt the model call and return the model response or a provider/model auth error.

Root Cause

Observed in OpenClaw 2026.4.25 bundled output (file hashes will churn between builds; locations cited as observed):

  • runModelRun() sets modelRun:true and promptMode:"none" (capability CLI module).
  • The execution attempt path propagates disableTools: params.opts.modelRun === true.
  • The selection module zeroes toolsRaw when disableTools || modelRun is true, but then still calls buildEmptyExplicitToolAllowlistError(...) because the global tools.alsoAllow has been expanded into an explicit allowlist of the form ["*", ...alsoAllow] by the sandbox tool-policy module.

So the modelRun path intentionally disables tools, but the empty-explicit-allowlist guard still evaluates the global tool policy and fails closed.

Fix Action

Fix / Workaround

We hit it during a gpt-5.5 routing cleanup on 2026-04-27 and initially rolled back a correct config patch because infer model run failed before making a provider call.

Workarounds

PR fix notes

PR #73031: fix(agents): skip empty allowlist guard for modelRun

Description (problem / solution / changelog)

Summary

openclaw infer model run aborts before any provider request when ~/.openclaw/openclaw.json has a non-empty tools.alsoAllow, because the empty explicit-allowlist guard still evaluates the global tool policy even though modelRun:true intentionally zeroes toolsRaw.

The fix adds a modelRun?: boolean parameter to buildEmptyExplicitToolAllowlistError and short-circuits to null when it is true. The embedded attempt path (attempt.ts) now passes modelRun: params.modelRun into the guard so model-only call shapes can run text-only without failing on a global tools.alsoAllow.

This keeps the existing fail-closed behavior for runtime disableTools conflicts and for ordinary agent runs whose explicit allowlist resolves to no callable tools (the original intent of #71292).

Repro

  1. Set in ~/.openclaw/openclaw.json:

    "tools": { "profile": "coding", "alsoAllow": ["lobster", "llm-task"] }
  2. Run:

    openclaw infer model run --local --model openai-codex/gpt-5.5 --prompt 'reply exactly: ok' --json

    Before this PR, fails with No callable tools remain after resolving explicit tool allowlist (...). After this PR, the model is reached.

Test added

src/agents/tool-allowlist-guard.test.ts — new case skips the empty-allowlist guard for modelRun call shapes. Asserts buildEmptyExplicitToolAllowlistError returns null when modelRun: true even with non-empty sources and zero callable tools. The existing disableTools: true fail-closed test is unchanged.

Validation

  • pnpm test src/agents/tool-allowlist-guard.test.ts — 7/7 passing
  • pnpm check:changed --staged — green (typecheck core/test, lint, import cycles, conflict markers, changelog attributions, etc.)
  • pnpm test:changed — 2521 passing; one unrelated pre-existing failure on src/agents/tools/cron-tool.schema.test.ts (job.delivery keys assertion is missing the new threadId introduced by upstream b6be422306 fix(cron): accept threaded delivery in gateway schema). Reproduces on bare upstream/main with my changes stashed, so it is not blocking.

Closes

Fixes #73024

AI assistance

This PR was prepared with Claude Code (Opus 4.7). Lightly tested locally — the unit test covers the guard contract; the end-to-end infer model run repro was not exercised live since it requires a live model account.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +1/-0)
  • src/agents/tool-allowlist-guard.test.ts (modified, +12/-0)
  • src/agents/tool-allowlist-guard.ts (modified, +7/-0)

Code Example

No callable tools remain after resolving explicit tool allowlist (tools.allow: *, lobster, llm-task)

---

"tools": {
     "profile": "coding",
     "alsoAllow": ["lobster", "llm-task"]
   }

---

openclaw infer model run --local --model openai-codex/gpt-5.5 --prompt 'reply exactly: ok' --json

---

No callable tools remain after resolving explicit tool allowlist (tools.allow: *, lobster, llm-task)

---

if (!params.modelRun && !params.disableTools && /* existing condition */) {
  throw buildEmptyExplicitToolAllowlistError(...);
}
RAW_BUFFERClick to expand / collapse

Summary

openclaw infer model run --local --model <id> --prompt <p> can abort before attempting any model call when ~/.openclaw/openclaw.json has a non-empty tools.alsoAllow.

The error is:

No callable tools remain after resolving explicit tool allowlist (tools.allow: *, lobster, llm-task)

This happens even though infer model run sets modelRun:true / disables tools intentionally. The target model and auth are valid. The same model succeeds when tools.alsoAllow is removed in a temp config.

Reproduce

  1. Configure ~/.openclaw/openclaw.json with:

    "tools": {
      "profile": "coding",
      "alsoAllow": ["lobster", "llm-task"]
    }
  2. Run:

    openclaw infer model run --local --model openai-codex/gpt-5.5 --prompt 'reply exactly: ok' --json

Actual

The command aborts with:

No callable tools remain after resolving explicit tool allowlist (tools.allow: *, lobster, llm-task)

No provider request is made. The gateway never reaches the model call.

Expected

Because modelRun:true disables tools for this call shape, tool allowlist validation should not fail the model smoke. The command should attempt the model call and return the model response or a provider/model auth error.

Root cause

Observed in OpenClaw 2026.4.25 bundled output (file hashes will churn between builds; locations cited as observed):

  • runModelRun() sets modelRun:true and promptMode:"none" (capability CLI module).
  • The execution attempt path propagates disableTools: params.opts.modelRun === true.
  • The selection module zeroes toolsRaw when disableTools || modelRun is true, but then still calls buildEmptyExplicitToolAllowlistError(...) because the global tools.alsoAllow has been expanded into an explicit allowlist of the form ["*", ...alsoAllow] by the sandbox tool-policy module.

So the modelRun path intentionally disables tools, but the empty-explicit-allowlist guard still evaluates the global tool policy and fails closed.

Observed source locations (bundled)

  • dist/capability-cli-*.jsrunModelRun()
  • dist/attempt-execution-*.js — propagates disableTools
  • dist/selection-*.jstoolsRaw zeroing + buildEmptyExplicitToolAllowlistError call
  • dist/sandbox-tool-policy-*.jstools.alsoAllow → explicit allowlist expansion

Suggested fix

Skip the empty-explicit-allowlist guard when tools are intentionally disabled:

if (!params.modelRun && !params.disableTools && /* existing condition */) {
  throw buildEmptyExplicitToolAllowlistError(...);
}

Alternatively, do not pass the global tool-policy block into that guard for modelRun/disableTools executions.

Impact

This breaks model/routing smoke tests and can produce false negatives during migrations.

We hit it during a gpt-5.5 routing cleanup on 2026-04-27 and initially rolled back a correct config patch because infer model run failed before making a provider call.

Workarounds

These production-path checks are unaffected:

  • openclaw cron run <id>
  • openclaw agent --agent <id> ...

A temp config that removes tools.alsoAllow also allows the same model/auth combo to succeed.

Environment

  • OpenClaw: 2026.4.25
  • Install: ~/homebrew/lib/node_modules/openclaw
  • macOS: Darwin 25.3.0

extent analysis

TL;DR

The issue can be fixed by modifying the condition in the empty-explicit-allowlist guard to skip it when tools are intentionally disabled.

Guidance

  • The root cause is the empty-explicit-allowlist guard evaluating the global tool policy even when modelRun is true, causing the model call to fail.
  • To verify the issue, run the openclaw infer model run command with a non-empty tools.alsoAllow in the config and check if it aborts before making a provider call.
  • The suggested fix is to modify the condition in the empty-explicit-allowlist guard to skip it when modelRun or disableTools is true.
  • As a temporary workaround, removing tools.alsoAllow from the config or using alternative commands like openclaw cron run or openclaw agent can allow the model call to succeed.

Example

if (!params.modelRun && !params.disableTools && /* existing condition */) {
  throw buildEmptyExplicitToolAllowlistError(...);
}

This code snippet shows the suggested modification to the empty-explicit-allowlist guard condition.

Notes

The issue is specific to OpenClaw version 2026.4.25 and may not affect other versions. The suggested fix and workarounds are based on the provided information and may need to be adapted to the specific use case.

Recommendation

Apply the suggested fix by modifying the condition in the empty-explicit-allowlist guard to skip it when modelRun or disableTools is true, as this will allow the model call to succeed even with a non-empty tools.alsoAllow in the config.

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 - ✅(Solved) Fix infer model run fails before model call when tools.alsoAllow is set and modelRun disables tools [1 pull requests, 1 participants]