#It doesn't work after updating to patch 2026.4.14

56 messages Β· Page 1 of 1 (latest)

serene oak
#

After updating to OpenClaw 2026.4.14 (and also persists after downgrade to 2026.4.12), the agent stops executing tool calls. It verbally acknowledges the request ("I will write the file"), but never invokes the actual tool (e.g., Write, Exec). The issue occurs with a custom OpenAI-compatible provider (TimeWeb Cloud AI).

Environment:

  • OpenClaw Version: 2026.4.14 (and 2026.4.12)
  • OS: Ubuntu 24.04
  • Node.js: 22.22.2
  • Provider: Custom (twc-agent/twc-agent), OpenAI-compatible (/v1/chat/completions)

Steps to Reproduce:

  1. Start a new session (/new).
  2. Send a command requiring a tool: Write "hello" to test.txt
  3. Agent responds: "I am writing the file."
  4. No file is created. No error in logs. Tool is not invoked.

Expected Behavior:
The Write tool should be executed, and the file should be created.

Actual Behavior:
Agent only provides a text response, no tool call. Session logs show no incomplete turn errors.

Additional Context:

  • openclaw infer model run --model twc-agent/twc-agent --prompt "Say OK" works (model returns OK).
  • openclaw config get tools.exec.host β†’ gateway
  • openclaw config get agents.defaults.sandbox.mode β†’ off
  • Approvals policy: openclaw exec-policy preset yolo applied.
  • Direct !pwd command (shell execution) also fails.
  • Suspected regression from changes in tool call handling (e.g., PRs #66145, #66167).
winter heathBOT
#

I’m checking the docs/code path for OpenAI-compatible tool calling, because this smells more like backend compatibility than the patch itself.

#

This smells less like #66145 / #66167, and more like the TimeWeb OpenAI-compatible layer not actually producing usable tool_calls on full agent turns.

OpenClaw docs already call out this exact failure class for OpenAI-compatible backends:

A few concrete things I’d try, in this order:

  1. Sanity check with a known tool-capable provider

    • Same install, same session flow, but switch to OpenAI/Anthropic/OpenRouter for one Write "hello" to test.txt test.
    • If that works, OpenClaw’s tool loop is fine, and the issue is provider compat.
  2. Reduce compat pressure

    • Set models.providers.<provider>.models[].compat.requiresStringContent: true
    • Set agents.defaults.localModelMode: "lean"
    • Try per-model streaming: false
#

That last one is especially worth testing here.

  1. Raw tool-call probe against TimeWeb
    Run a direct Chat Completions request that includes tools. If the raw response never returns tool_calls, OpenClaw cannot make it execute tools.

    Example shape:

    curl -sS "$BASE/v1/chat/completions" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "twc-agent",
        "stream": false,
        "messages": [
          { "role": "user", "content": "Call the ping tool. Do not answer with plain text." }
    
#
       ],
       "tools": [
         {
           "type": "function",
           "function": {
             "name": "ping",
             "description": "Returns pong",
             "parameters": {
               "type": "object",
               "properties": {},
               "additionalProperties": false
             }
           }
         }
       ],
#
       "tool_choice": "required"
     }' | jq

You want to see choices[0].message.tool_calls, not plain assistant text.

One extra clue: TimeWeb’s own docs say their OpenAI-compatible API is not fully OpenAI-compatible, and their MCP docs mention streaming caveats. So streaming: false is a very plausible workaround:

Also, don’t use compat.supportsTools: false as a β€œfix” unless you’re just testing, because that disables tool calling by design.

If you want, paste:

  • openclaw status --all
  • openclaw models status --probe
  • the redacted raw curl response above
#

and I can help narrow it down fast.

serene oak
#

openclaw models status --probe

🦞 OpenClaw 2026.4.12 (1c0672b)
I'm basically a Swiss Army knife, but with more opinions and fewer sharp edges.

β”‚
β—‡
Config : ~/.openclaw/openclaw.json
Agent dir : ~/.openclaw/agents/main/agent
Default : twc-agent/twc-agent
Fallbacks (0) : -
Image model : -
Image fallbacks (0): -
Aliases (0) : -
Configured models (1): twc-agent/twc-agent

Auth overview
Auth store : ~/.openclaw/agents/main/agent/auth-profiles.json
Shell env : off
Providers w/ OAuth/tokens (0): -

  • twc-agent effective=models.json:<token> | models.json=<token> | source=models.json: ~/.openclaw/agents/main/agent/models.json

OAuth/token status

  • none

Auth probes
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Model β”‚ Profile β”‚ Status β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ twc-agent/twc-agent β”‚ models.json (api_key) β”‚ ok Β· 9.2s β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Probed 1 target in 22.1s

winter heathBOT
#

That probe is useful, it rules out auth/reachability. It does not prove the backend supports OpenClaw-style tool calling.

So the problem is now very likely in the TimeWeb OpenAI-compatible tool-call path, not in exec policy or gateway reachability.

I’d try this exact config tweak next, then restart the gateway:

{
  agents: {
    defaults: {
      localModelMode: "lean",
      models: {
        "twc-agent/twc-agent": {
          streaming: false
        }
      }
#
    }
  },
  models: {
    providers: {
      "twc-agent": {
        models: [
          {
            id: "twc-agent",
            compat: {
              requiresStringContent: true
            }
          }
        ]
      }
    }
#
  }
}

Important: merge that into your existing config/provider entry, don’t replace the whole provider block.

Why this is my top guess:

Especially relevant: if your TimeWeb agent has MCP servers attached, their docs say SSE streaming has caveats there, so streaming: false is a strong test.

#

If that still fails, the next decisive check is a raw /v1/chat/completions request with a tools payload. If TimeWeb returns plain text instead of tool_calls, OpenClaw can’t force tool execution on top of it.

If you want, paste either:

  1. openclaw status --all, or
  2. the redacted raw tool-call response

and I’ll help narrow it down further.

serene oak
#

openclaw gateway restart

Invalid config at /root/.openclaw/openclaw.json:\n- models.providers.twc-agent.models.0: Unrecognized key: "compact"

  • agents.defaults: Unrecognized key: "localModelMode"

🦞 OpenClaw 2026.4.12 (1c0672b)
I've survived more breaking changes than your last three relationships.

Config invalid
File: ~/.openclaw/openclaw.json
Problem:

  • models.providers.twc-agent.models.0: Unrecognized key: "compact"
  • agents.defaults: Unrecognized key: "localModelMode"

Run: openclaw doctor --fix
Gateway aborted: config is invalid.
models.providers.twc-agent.models.0: Unrecognized key: "compact"
agents.defaults: Unrecognized key: "localModelMode"
Fix the config and retry, or run "openclaw doctor" to repair.

winter heathBOT
#

I gave you a key that your installed version doesn’t know, that’s on me. Let me check when that setting landed and give you a version-safe path.

#

Yep, that part is on me, I mixed current docs with your 2026.4.12 install. agents.defaults.localModelMode is not in 2026.4.12 yet, so remove it.

Also, this is separate, but your config already has another invalid field:

  • models.providers.twc-agent.models.0.compact β†’ remove it
  • agents.defaults.localModelMode β†’ remove it

For 2026.4.12, the safer test config is just:

{
  agents: {
    defaults: {
      models: {
        "twc-agent/twc-agent": {
          streaming: false
#
        }
      }
    }
  },
  models: {
    providers: {
      "twc-agent": {
        models: [
          {
            id: "twc-agent",
            compat: {
              requiresStringContent: true
            }
          }
        ]
#
      }
    }
  }
}

So the next steps are:

  1. delete agents.defaults.localModelMode
  2. delete models.providers.twc-agent.models[0].compact
  3. keep/add:
    • agents.defaults.models["twc-agent/twc-agent"].streaming: false
    • models.providers.twc-agent.models[0].compat.requiresStringContent: true
  4. restart gateway
  5. retest Write "hello" to test.txt
#

If it still just answers in plain text after that, I’d go straight to the raw tools curl probe, because then it’s almost certainly the TimeWeb compat layer not returning tool_calls.

Relevant docs:

If you want, paste the redacted twc-agent model block from ~/.openclaw/openclaw.json, and I can point to the exact lines to keep/remove.

serene oak
#

OpenClaw status --all

Overview
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Item β”‚ Value β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Version β”‚ 2026.4.12 β”‚
β”‚ OS β”‚ linux 6.8.0-110-generic (x64) β”‚
β”‚ Node β”‚ 22.22.2 β”‚
β”‚ Config β”‚ ~/.openclaw/openclaw.json β”‚
β”‚ Dashboard β”‚ http://127.0.0.1:18789/ β”‚
β”‚ Tailscale β”‚ off β”‚
β”‚ Channel β”‚ stable (default) β”‚
β”‚ Update β”‚ pnpm Β· npm update 2026.4.14 β”‚
β”‚ Gateway β”‚ local Β· ws://127.0.0.1:18789 (local loopback) Β· unreachable (timeout) β”‚
β”‚ Security β”‚ Run: openclaw security audit --deep β”‚
β”‚ Gateway self β”‚ unknown β”‚
β”‚ Gateway service β”‚ systemd installed Β· enabled Β· running (pid 1191, state active) β”‚
β”‚ Node service β”‚ systemd not installed β”‚
β”‚ Agents β”‚ 1 total Β· 1 bootstrapping Β· 1 active Β· 3 sessions β”‚
β”‚ Secrets β”‚ none β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

#

Channels
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Channel β”‚ Enabled β”‚ State β”‚ Detail β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Telegram β”‚ ON β”‚ OK β”‚ token config (sha256:403aa03f Β· len 46) Β· accounts 1/1 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Telegram accounts
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Account β”‚ Status β”‚ Notes β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ default β”‚ OK β”‚ token:config β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Agents
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Agent β”‚ Bootstrap file β”‚ Sessions β”‚ Active β”‚ Store β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ main β”‚ PRESENT β”‚ 3 β”‚ 6m ago β”‚ ~/.openclaw/agents/main/sessions/sessions. β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ json β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

#

Diagnosis (read-only)

Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /root/.openclaw/openclaw.json
Bind: loopback

βœ“ Config: /root/.openclaw/openclaw.json
βœ“ Secret diagnostics (0)
βœ“ Restart sentinel: none
! Port 18789
Port 18789 is already in use.

  • pid 1191 root: openclaw-gateway (127.0.0.1:18789)
  • Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
    ! Tailscale: off Β· unknown
    βœ“ Skills: 7 eligible Β· 0 missing Β· /root/.openclaw/workspace
    βœ“ Plugin compatibility (none)
    ! Channel issues skipped (gateway unreachable)

Gateway health:
timeout

Pasteable debug report. Auth tokens redacted.
Troubleshooting: https://docs.openclaw.ai/troubleshooting

winter heathBOT
#

Ah, this changes the diagnosis a bit.

The biggest red flag in that output is not the model probe, it’s this:

  • Gateway ... unreachable (timeout)
  • Agents: 1 total Β· 1 bootstrapping

So before chasing TimeWeb tool-calling, I’d fix gateway health / stuck bootstrap first. If the gateway RPC is timing out, tool execution symptoms can just be downstream noise.

Please run these next and paste them:

openclaw gateway status
openclaw logs --follow

If openclaw logs --follow can’t get through, use the file log fallback from the docs:

#
tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)"

What I’m looking for:

  • openclaw gateway status should say Runtime: running and RPC probe: ok
  • the log should show whether the process is wedged, timing out, or stuck bootstrapping

One more very specific thing: if that 1 bootstrapping never clears, check whether the agent workspace still has a stale BOOTSTRAP.md. We’ve seen that keep agents stuck in bootstrap mode and break normal runs.

Docs:

Once the gateway is healthy, then I’d go back to the TimeWeb-specific tests (streaming: false, compat.requiresStringContent: true, raw tools curl probe). Right now the RPC timeout is the louder problem.

#

I think we found it.

Bootstrap file: PRESENT on an already-running agent is a big clue. Per the docs, BOOTSTRAP.md is first-run only and should be removed when bootstrapping finishes:

So if this is not a brand-new setup, I’d treat that as stale bootstrap state.

What I’d do

  1. Find the active workspace BOOTSTRAP.md
    Usually it’s in ~/.openclaw/workspace/BOOTSTRAP.md unless you changed the workspace path.

  2. Move it aside instead of deleting it, for safety.
    Example:

#
   mv ~/.openclaw/workspace/BOOTSTRAP.md ~/.openclaw/workspace/BOOTSTRAP.md.bak
  1. Restart the gateway:

    openclaw gateway restart
    
  2. Re-run:

    openclaw status --all
    

What I’d expect after that:

#
  • bootstrapping should drop to 0
  • gateway health should improve
  • then we can retest the tool-call issue cleanly

If you’re not sure where the file is, run:

find ~/.openclaw -name BOOTSTRAP.md

If you paste that result, I can tell you which one to move.

#

Yep, this is pointing much more at a wedged gateway + stale bootstrap than at TimeWeb itself.

Key bits from that report:

  • gateway process is alive on 127.0.0.1:18789
  • but Gateway health = timeout
  • active workspace is /root/.openclaw/workspace
  • earlier status showed Bootstrap file: PRESENT

So I’d do this next, in this order:

mv /root/.openclaw/workspace/BOOTSTRAP.md /root/.openclaw/workspace/BOOTSTRAP.md.bak
openclaw gateway stop
openclaw gateway start
openclaw status --all
#

If the first command says the file isn’t there, locate it first:

find /root/.openclaw -name BOOTSTRAP.md

What I’m hoping to see after restart:

  • Gateway ... reachable
  • bootstrapping drops to 0
  • then retest Write "hello" to test.txt

At this point I would pause the TimeWeb-specific debugging until this is clean, because a stuck bootstrap / unhealthy gateway can absolutely make tool execution look broken.

Docs:

#

If you paste the next openclaw status --all after that, I can tell pretty quickly whether we’ve cleared the real blocker.

serene oak
#

openclaw gateway status

🦞 OpenClaw 2026.4.12 (1c0672b)
If it's repetitive, I'll automate it; if it's hard, I'll bring jokes and a rollback plan.

β”‚
β—‡
Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-04-16.log
Command: /usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789

Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json

Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.

Runtime: running (pid 1191, state active, sub running, last exit 0, reason 0)
RPC probe: ok

Listening: 127.0.0.1:18789

#

Agents
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Agent β”‚ Bootstrap file β”‚ Sessions β”‚ Active β”‚ Store β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ main β”‚ ABSENT β”‚ 3 β”‚ 1m ago β”‚ ~/.openclaw/agents/main/ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ sessions/sessions.json β”‚

winter heathBOT
#

Nice, that clears the gateway side.

openclaw gateway status looks healthy now, so I’d move the blame back to the provider/tool-calling path.

Next decisive test

Hit the TimeWeb endpoint directly with a tiny tools payload and stream: false:

curl -sS "$BASE/v1/chat/completions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "twc-agent",
    "stream": false,
    "messages": [
      { "role": "user", "content": "Call the ping tool. Do not answer with plain text." }
#
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "ping",
          "description": "test tool",
          "parameters": {
            "type": "object",
            "properties": {},
            "additionalProperties": false
          }
        }
      }
    ],
#
    "tool_choice": "required"
  }' | jq

What matters

If the response contains:

  • choices[0].message.tool_calls β†’ good, the provider can emit tool calls
  • only plain assistant content and no tool_calls β†’ that’s the real problem, and OpenClaw can’t force tools on top of it

At that point:

  • no tool_calls β†’ TimeWeb compat issue
  • has tool_calls β†’ likely OpenClaw bug / compatibility edge, and then I’d want:
    • openclaw logs --follow
    • one failing Write "hello" to test.txt turn
#

Perfect, that clears the bootstrap angle too.

So now we’ve ruled out the two big local blockers:

  • gateway health, fixed
  • stale BOOTSTRAP.md, gone

At this point I’d call the remaining suspect TimeWeb’s OpenAI-compatible tool-call behavior. That also fits the fact that it repros on both 2026.4.12 and 2026.4.14.

So the next step is still the raw provider probe:

curl -sS "$BASE/v1/chat/completions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
#
    "model": "twc-agent",
    "stream": false,
    "messages": [
      { "role": "user", "content": "Call the ping tool. Do not answer with plain text." }
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "ping",
          "description": "test tool",
          "parameters": {
            "type": "object",
            "properties": {},
            "additionalProperties": false
#
          }
        }
      }
    ],
    "tool_choice": "required"
  }' | jq

What I need to know from that result:

  • has tool_calls β†’ likely OpenClaw compat bug
  • no tool_calls, only plain text β†’ provider/model issue, which would explain why write and !pwd both β€œsound like they work” but never actually run

If you paste that result, we should be able to stop guessing and pin it down.

serene oak
#

i used this query and take answer:
{
"id": "chatcmpl-315cea15-c423-445e-87ac-54f3c0af8f72",
"created": 1776351165,
"model": "anthropic/claude-sonnet-4-6",
"object": "chat.completion",
"choices": [
{
"finish_reason": "tool_calls",
"index": 0,
"message": {
"content": null,
"role": "assistant",
"tool_calls": [
{
"index": 0,
"caller": {
"type": "direct"
},
"function": {
"arguments": "{}",
"name": "ping"
},
"id": "toolu_019XnmDeQC48pcGEEADmXSYw",
"type": "function"
}
]
}
}
],
"usage": {
"completion_tokens": 19,
"prompt_tokens": 649,
"total_tokens": 668,
"completion_tokens_details": {
"reasoning_tokens": 0,
"text_tokens": 19
},
"prompt_tokens_details": {
"cached_tokens": 0,
"cache_creation_tokens": 0,
"cache_creation_token_details": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0
}
},
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}

winter heathBOT
#

Oh, nice, that’s the smoking gun.

That response proves the provider can return valid tool_calls. So the problem is probably not β€œTimeWeb can’t do tools at all”, it’s much more likely:

non-streaming tool calls work, but OpenClaw’s normal streaming path is not seeing them correctly

That fits your symptom very well.

Best next test

Force this model to run non-streaming inside OpenClaw:

{
  agents: {
    defaults: {
      models: {
#
        "twc-agent/twc-agent": {
          streaming: false
        }
      }
    }
  }
}

Then restart the gateway and retry:

openclaw gateway restart

If that makes Write "hello" to test.txt start working, then you’ve basically confirmed a streaming compatibility issue with this OpenAI-compatible backend.

#

Why I think that

Your direct probe returned:

  • finish_reason: "tool_calls"
  • message.tool_calls: [...]

But OpenClaw normally runs with stream: true, and some OpenAI-compatible backends are fine in non-stream mode while being weird or incomplete in streamed tool-call chunks.

If streaming: false still does not fix it

Then I’d capture one more thing:

  • the same raw provider request with "stream": true

If non-stream works and stream breaks, that is a very solid bug report / compatibility repro.

If you test streaming: false and report back, we’re very close to a real answer here.

serene oak
#

don't work with streaming: false and streaming: true

winter heathBOT
#

That’s actually really helpful.

If:

  • raw tiny tool-call request does return tool_calls
  • OpenClaw still fails with both streaming: false and streaming: true

then the remaining difference is probably prompt/tool-schema size, not basic tool-call support.

In other words, the provider/model seems able to do one tiny forced tool, but may be falling over when OpenClaw sends the full agent prompt + full tool inventory.

Best next test

Temporarily shrink OpenClaw’s tool surface to just the essentials:

{
#
  tools: {
    allow: ["read", "write", "exec", "process"]
  }
}

Then:

openclaw gateway restart

Start a fresh session with /new and retry:

  • Write "hello" to test.txt
  • !pwd
#

This is basically the manual version of the leaner local-model mode I mentioned earlier, but using config that should work on 2026.4.12.

How to read the result

  • If this starts working: your backend/model can do tool calls, but it is choking on OpenClaw’s full tool schema surface
  • If this still fails: then I’d treat it as a real OpenClaw compat bug / provider quirk, and the next thing I’d want is:
    • openclaw logs --follow
    • one failing turn
    • then probably a GitHub issue with the raw working curl result included

Relevant troubleshooting doc:
https://docs.openclaw.ai/help/troubleshooting#local-openai-compatible-backend-works-directly-but-fails-in-openclaw

If you try the tools.allow test, we’re down to a very small set of possibilities.

serene oak
#

may be it is bug openclaw ?
Tool calls not executed with custom OpenAI-compatible provider.
Evidence:

  • βœ… Direct curl with tool_calls works: returns proper tool_calls payload
  • βœ… openclaw infer model run works: returns "OK"
  • βœ… /tools shows write and exec in the list
  • ❌ !pwd and !echo do nothing (agent responds verbally, no file created)
winter heathBOT
#

Yeah, at this point I think that’s a fair conclusion.

More precisely, it looks like an OpenClaw compatibility bug / unsupported edge with this custom OpenAI-compatible provider, not just a bad config.

Why I’m saying that:

  • βœ… direct raw request returns valid tool_calls
  • βœ… OpenClaw sees the tools (/tools)
  • βœ… gateway/bootstrap issues are cleared
  • βœ… changing streaming didn’t fix it
  • ❌ OpenClaw still turns the request into plain text instead of invoking the tool

So I’d file this as a bug here:

https://github.com/openclaw/openclaw/issues

If you want, this is the core claim I’d put in the issue:

#

OpenClaw does not execute tool calls with a custom OpenAI-compatible provider, even though the provider returns valid tool_calls in direct raw requests.

Useful things to include in the issue:

  • OpenClaw version(s): 2026.4.12, 2026.4.14
  • provider type: custom OpenAI-compatible /v1/chat/completions
  • exact symptom: agent says it will run write / exec, but no tool is invoked
  • raw working curl result showing finish_reason: "tool_calls" and message.tool_calls
  • note that streaming: false did not help
  • note that /tools shows write and exec
  • note that !pwd / !echo also fail the same way
  • redacted provider config for twc-agent
  • relevant openclaw logs --follow snippet, if you have one

If you want, I can help you turn all the evidence from this thread into a tight GitHub issue body you can paste directly.

serene oak
#

yes, just do it

winter heathBOT
#

Paste this into https://github.com/openclaw/openclaw/issues/new:

## Summary

OpenClaw does not execute tool calls when using a custom OpenAI-compatible provider, even though the provider returns valid `tool_calls` in direct raw requests.

The agent verbally acknowledges the action ("I am writing the file"), but never invokes the actual tool (`write`, `exec`, etc).

## Environment

- OpenClaw versions tested: `2026.4.14`, `2026.4.12`
- OS: Ubuntu 24.04
- Node.js: 22.22.2
- Provider: custom OpenAI-compatible provider (`/v1/chat/completions`)
- Model ref in OpenClaw: `twc-agent/twc-agent`
#
- Backend: TimeWeb Cloud AI

## Repro

1. Start a new session (`/new`)
2. Ask for a tool action, for example:
   - `Write "hello" to test.txt`
   - `!pwd`
   - `!echo hi`
3. OpenClaw responds in natural language as if it will do the action
4. No tool is actually invoked, and no file/output is produced

## Expected

OpenClaw should call the relevant tool (`write`, `exec`, etc) and execute it.
#

## Actual

OpenClaw only responds with plain assistant text. No tool call is executed.

## Evidence collected

### OpenClaw-side

- `openclaw infer model run --model twc-agent/twc-agent --prompt "Say OK"` works
- `/tools` shows tools like `write` and `exec`
- Gateway health was checked and is OK:
  - `openclaw gateway status` β†’ `RPC probe: ok`
- Bootstrap/stuck-bootstrap issue was ruled out:
  - agent bootstrap file is now absent
#

### Provider-side

Direct raw request to the provider with a tool definition returns valid `tool_calls`.

Example result shape:

```json
{
  "choices": [
    {
      "finish_reason": "tool_calls",
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
#

{
"function": {
"name": "ping",
"arguments": "{}"
},
"id": "toolu_...",
"type": "function"
}
]
}
}
]
}


So the backend **can** emit tool calls.
#

## Additional tests already tried

- Tested on both `2026.4.12` and `2026.4.14`
- Tried per-model:
  - `streaming: false`
  - `streaming: true`
- Same behavior in both cases
- Tried reducing variables during diagnosis (gateway health, bootstrap state, etc), but the issue persisted

## Current hypothesis

This looks like an OpenClaw compatibility bug / unsupported edge with custom OpenAI-compatible providers:

- direct provider requests return valid `tool_calls`