#Complete removal so I can start over from scratch? My install has never been right, CANNOT remove!

1 messages · Page 1 of 1 (latest)

last arrow
#

Everything running inside WSL2:

On my first install I left in the middle for a few hours, after I finally came back and finished, it has just never worked.

I am running a local TensorRT-LLM server (openai compatible endpoint, works just like a cloud provider) the model seems to get setup fine.
I can even see the server getting hit, sometimes it's okay and returns 200 (heartbeat, limited other operations) but most of the time it throws a 400 bad request, no body (UI), if it gets hit at all.
I have never gotten a successful response from the chat tab in the control UI (which I think is not functional by default from what I have been reading?)

I tried to setup Signal, downloaded signal-cli, did everything to register a dedicated number, captcha, all that, everything seemed to work, but the config was still broken.
Only after a few runs of multiple "ladders" of openclaw <command> in the terminal did the config finally show configured and running, but still no messages go through (allowList). Also, now all of the other channel setup options are gone.
I think it should automatically route without the bindings section?

I keep seeing stuff like this:
gateway connect failed: Error: unauthorized: gateway token mismatch (provide gateway auth token)
◇
Health check failed: gateway closed (1008): unauthorized: gateway token mismatch (provide gateway auth token)
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /root/.openclaw/openclaw.json
Bind: loopback

Auth is setup on the gateway (token)

I have tried all of the persistent user services fixes the gateway still doesn't look like it is staying up 100% of the time.
I just noticed that it looks like it couldn't move some files to the trash, looks like it's having trouble doing a full-reset and I need to go hunting for stragglers. Still, after an update and reconfiguring everything I should have overwritten everything that was broken.

Why is it so hard just to get this thing to reply, "Hello world!"?

reef ermineBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

stuck zephyrBOT
#

That gateway closed (1008): unauthorized: gateway token mismatch is the “nothing will ever work until this is fixed” problem — and in WSL2 it’s very often caused by accidentally running some commands as root and others as your normal user, so you end up with two different configs/tokens.

You even have the smoking gun here: Config: /root/.openclaw/openclaw.json → that’s the root profile.

1) First: get the 60‑second diagnostics (safe to paste)

Please run these and paste the output (don’t paste tokens manually — these commands redact safely):

openclaw --version
openclaw status --all
openclaw gateway status

Docs runbook: https://docs.openclaw.ai/help/troubleshooting and https://docs.openclaw.ai/gateway/troubleshooting

2) Fix the token mismatch (most common root cause)

OpenClaw will show this clearly in openclaw gateway status (it reports Config (cli) vs Config (service)). If those paths differ, you’re editing one config while the service is running from another.

#

Typical WSL2 failure mode:

  • Gateway service runs as your normal user (config under /home/<you>/.openclaw/...)
  • You run CLI commands with sudo sometimes (config under /root/.openclaw/...)
  • Tokens diverge → endless “token mismatch”.

Fix: pick one user and run everything as that user (recommend: non-root), then reinstall the service metadata from that same profile:

openclaw gateway install --force
openclaw gateway restart

(Those exact commands are in the official troubleshooting page: https://docs.openclaw.ai/gateway/troubleshooting)

3) Control UI chat is supposed to work

Control UI talks directly to the Gateway WS and supports chat.send etc: https://docs.openclaw.ai/web/control-ui

#

To connect locally:

  • open http://127.0.0.1:18789/
  • paste the token from gateway.auth.token into the UI settings (the UI stores connect.params.auth.token)

FAQ section: https://docs.openclaw.ai/help/faq#how-do-i-authenticate-the-dashboard-token-on-localhost-vs-remote

4) Your Signal config issue: it’s allowFrom + pairing (not “allowList”)

Signal docs (minimal config example): https://docs.openclaw.ai/channels/signal

Key points:

  • The field is allowFrom (phone numbers / uuid:
)
  • Default recommended DM mode is dmPolicy: "pairing", which means you must approve the pairing code:
openclaw pairing list signal
openclaw pairing approve signal <CODE>
#

5) Why your local “OpenAI-compatible” TensorRT-LLM endpoint gets 400s

The “heartbeat works but chat/tool-ish actions 400” pattern usually means: your server accepts basic OpenAI-ish requests but doesn’t support the full set of fields OpenClaw sends (notably tool calling / schemas / streaming options). OpenClaw is extremely tool-heavy, so “OpenAI compatible” has to include those pieces, not just /v1/chat/completions.

Once we have openclaw status --all + logs, we can tell if it’s failing on tool schema vs something else.


If you’re ready to nuke it from orbit and reinstall cleanly, the supported uninstall path is:

openclaw uninstall --all --yes --non-interactive

Docs: https://docs.openclaw.ai/install/uninstall

But I’d grab the status --all + gateway status first — it usually makes the root-vs-user mismatch instantly obvious.

last arrow
#

│ Version │ 2026.2.24
│ OS │ linux 6.6.87.2-microsoft-standard-WSL2 (x64)
│ Node │ 24.13.1
│ Config │ ~/.openclaw/openclaw.json
│ Dashboard │ http://127.0.0.1:18789/
│ Tailscale │ off
│ Channel │ stable (default)
│ Update │ pnpm · npm latest 2026.2.24
│ Gateway │ local · ws://127.0.0.1:18789 (local loopback) · reachable 19ms · auth token
│ Security │ Run: openclaw security audit --deep
│ Gateway self │ myComputer (IP removed) app 2026.2.24 linux 6.6.87.2-microsoft-standard-WSL2
│ Gateway service │ systemd installed · enabled · running (pid 112173)
│ Node service │ systemd not installed
│ Agents │ 1 total · 1 bootstrapping · 0 active · 1 sessions
Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/me/.openclaw/openclaw.json
Bind: loopback

✓ Config: /home/me/.openclaw/openclaw.json
✓ Restart sentinel: none
! Port 18789
Port 18789 is already in use.

  • pid 112173 me: openclaw-gateway (127.0.0.1:18789)
  • Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
    ! Tailscale: off · unknown
    error: Error: spawn tailscale ENOENT
    ✓ Skills: 6 eligible · 0 missing · /home/me/.openclaw/workspace
    ✓ Channel issues (none)
    Service: systemd (enabled)
    File logs: /tmp/openclaw/openclaw-2026-02-25.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 112173, state active, sub running, last exit 0, reason 0)
RPC probe: ok
Listening: 127.0.0.1:18789

stuck zephyrBOT
#

Nice — that output shows your Gateway is actually healthy now:

  • Config (cli) == Config (service) (~/.openclaw/openclaw.json)
  • RPC probe: ok
  • Listening on 127.0.0.1:18789

So the earlier Config: /root/.openclaw/openclaw.json + token mismatch was almost certainly from having run some openclaw commands under sudo/root at some point (WSL2 makes this super easy to do accidentally). From here on out: try to run everything as the same user (me), no sudo.

The remaining blocker is almost certainly your local TensorRT-LLM “OpenAI compatible” API mode

The Control UI chat uses the same agent/model path as normal messaging. A 400 from the model usually means one of these:

  1. Your provider is configured as api: "openai-responses" but your server only implements /v1/chat/completions (common).
  2. Your server rejects some OpenAI fields OpenClaw sends (tools/function calling related fields, streaming options, etc).

OpenClaw supports multiple “OpenAI-compatible” API modes — notably openai-completions vs openai-responses. Config example page shows openai-responses, and the config reference explicitly lists openai-completions | openai-responses | ... as valid values.
Docs: https://docs.openclaw.ai/gateway/configuration-examples and https://docs.openclaw.ai/gateway/configuration-reference

#

What I need from you (2 commands + 1 log snippet)

Run:

openclaw models status
openclaw logs --follow

Then, while logs --follow is running, go to the Control UI and send a simple “hello”.

Paste the part of the log where it hits your local model and shows the HTTP 400 (it’ll usually show which endpoint it called, like /v1/responses vs /v1/chat/completions, and often the error body even if the UI shows “no body”).

Also paste (redact the key) just your provider block:

openclaw config get models
#

I’m specifically looking for models.providers.<yourProvider>.api and baseUrl.

Two quick clarifications from your earlier notes

  • Control UI chat is functional (it’s not “disabled by default”). If it never responds, it’s because the agent run is failing upstream (model 400, auth, etc). Docs: https://docs.openclaw.ai/web/control-ui
  • Routing: you generally don’t need bindings for “reply back to where it came from”. Bindings are for multi-agent routing rules, not basic reply behavior.

If you want a clean wipe/reinstall anyway (WSL-safe approach)

Start with a dry run so you can see what it thinks it will remove:

openclaw uninstall --dry-run

Then:

#
openclaw uninstall --all --yes --non-interactive

Docs: https://docs.openclaw.ai/install/uninstall

But given your gateway is healthy now, I’d try to fix the provider api mode first — your “agent bootstrapping forever” symptom often clears up automatically once the model calls stop 400’ing.

last arrow
#

Config : ~/.openclaw/openclaw.json
Agent dir : ~/.openclaw/agents/main/agent
Default : custom-127-0-0-1-8000/Qwen3-Next
Fallbacks (0) : -
Image model : -
Image fallbacks (0): -
Aliases (1) : Qwen3-Next-quant -> custom-127-0-0-1-8000/Qwen3-Next
Configured models (1): custom-127-0-0-1-8000/Qwen3-Next

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

  • custom-127-0-0-1-8000 effective=models.json:tensorrt_llm | models.json=tensorrt_llm | source=models.json: ~/.openclaw/agents/main/agent/models.json

OAuth/token status

  • none

Log output during "hello":
...
21:41:36 debug agent/embedded {"subsystem":"agent/embedded"} embedded run prompt start: runId=529de655-x-x-x-b2c1fde4e67d sessionId=9fb6edc9-x-x-x-c1762b29a6d6
21:41:36 debug agent/embedded {"subsystem":"agent/embedded"} embedded run compaction start: runId=529de655-x-x-x-b2c1fde4e67d
21:41:36 debug agent/embedded {"subsystem":"agent/embedded"} embedded run compaction retry: runId=529de655-x-x-x-b2c1fde4e67d
21:41:36 debug agent/embedded {"subsystem":"agent/embedded"} embedded run agent start: runId=529de655-x-x-x-b2c1fde4e67d
21:41:36 warn agent/embedded {"subsystem":"agent/embedded"} embedded run agent end: runId=529de655-x-x-x-b2c1fde4e67d isError=true error=400 status code (no body)
21:41:36 debug agent/embedded {"subsystem":"agent/embedded"} embedded run compaction start: runId=529de655-x-x-x-b2c1fde4e67d
then repeats that block again ^ before rejecting compaction and aborting in-flight compaction

Terminal:
INFO: 127.0.0.1:58440 - "POST /v1/chat/completions HTTP/1.1" 400 Bad Request
Control UI: 400 status code (no body)

"mode": "merge",
"providers": {
"custom-127-0-0-1-8000": {
"baseUrl": "http://127.0.0.1:8000/v1",
"apiKey": "OPENCLAW_REDACTED",
"auth": "api-key",
"api": "openai-completions",
"models": [
{
"id": "Qwen3-Next",
"name": "Qwen3-Next (Custom Provider)",
"api": "openai-completions"

stuck zephyrBOT
#

This is great data — your Gateway side is healthy now (RPC probe: ok, config paths match, service running). The “Hello” failure is 100% happening between OpenClaw → your TensorRT-LLM OpenAI server, which is returning:

POST /v1/chat/completions 
 400 Bad Request (no body)

So we need to figure out which part of the OpenAI Chat Completions contract your server rejects. OpenClaw will typically send more than “messages+model” (notably streaming + tool schemas), and a lot of “OpenAI-compatible” servers 400 on those.

1) Quick compatibility matrix (run these directly against TensorRT-LLM)

Run each and tell me which one first returns 400 (and if any returns a JSON error body).

A) Absolute minimum (should work everywhere)

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":"hi"}],"max_tokens":32}' | head -200

B) With stream: true (OpenClaw often streams)

#
curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","stream":true,"messages":[{"role":"user","content":"hi"}],"max_tokens":32}' | head -50

C) With a tiny tools payload (this is the big one)

If this 400s, that’s basically the explanation for why OpenClaw can’t “hello world” with that backend.

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model":"Qwen3-Next",
"messages":[{"role":"user","content":"Say hi"}],
"max_tokens":32,
"tools":[{"type":"function","function":{"name":"noop","description":"noop","parameters":{"type":"object","properties":{},"additionalProperties":false}}}],
#
"tool_choice":"auto"
}' | head -200

2) What the result means

  • If (A) fails: your TensorRT-LLM server isn’t actually compatible with basic Chat Completions for that model/id (or it requires some extra field). OpenClaw can’t fix that.
  • If (A) works but (B) fails: your server likely doesn’t support OpenAI-style streaming; OpenClaw will struggle hard.
  • If (A) and (B) work but (C) fails: your server doesn’t support OpenAI tool calling (tools / JSON Schema). OpenClaw fundamentally relies on tool calling, so you’ll need a different serving stack (or a proxy that properly supports tool-calling semantics).

3) Why you see compaction retries then abort

That log snippet is consistent with: OpenClaw tries to run compaction + agent run, but every model call 400s, so it keeps retrying compaction and then gives up.

4) Signal side note (once model works)

Your Signal config bits are likely fine, but you won’t see any replies until the model stops 400’ing. Also the field is allowFrom + pairing approvals (docs): https://docs.openclaw.ai/channels/signal


#

Reply with the outputs of A/B/C (headers + first ~50–200 lines). That’ll tell us immediately whether this is “missing max_tokens”, “no streaming”, or “no tools support”.

last arrow
#

None of those fail... LMFAO!
C:
~$ curl -sS -D- http://127.0.0.1:8000/v1/chat/completions
-H 'Content-Type: application/json'
-d '{
"model":"Qwen3-Next",
"messages":[{"role":"user","content":"Say hi"}],
"max_tokens":32,
"tools":[{"type":"function","function":{"name":"noop","description":"noop","parameters":{"type":"object","properties":{},"additionalProperties":false}}}],"tool_choice":"auto"
}' | head -200
HTTP/1.1 200 OK
date: Wed, 25 Feb 2026 21:58:39 GMT
server: uvicorn
content-length: 559
content-type: application/json

{"id":"chatcmpl-7a318d5c0e6c40089f31441f5b42718a","object":"chat.completion","created":1772056719,"model":"Qwen3-Next","choices":[{"index":0,"message":{"role":"assistant","content":"Hi! How can I help you today?","reasoning_content":"","reasoning":null,"tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null,"mm_embedding_handle":null,"disaggregated_params":null,"avg_decoded_tokens_per_iter":1.0}],"usage":{"prompt_tokens":133,"total_tokens":143,"completion_tokens":10,"prompt_tokens_details":{"cached_tokens":0}},"prompt_token_ids":null}

Signal config:
"channels": {
"signal": {
"enabled": true,
"account": "+1xxxxxxxxxx",
"cliPath": "signal-cli",
"autoStart": true,
"dmPolicy": "allowlist",
"allowFrom": [
1yyyyyyyyyy
],
"groupPolicy": "allowlist"
}
},
hmmmm, don't see a + there in the allowFrom....

stuck zephyrBOT
#

Perfect — that means your TensorRT-LLM endpoint does support tools + tool_choice. So the 400 from OpenClaw is not “no tool calling support”.

What this usually means next is: OpenClaw is sending some other field / message shape that your server rejects (and it returns a bare 400).

Step 1: find the exact “one field” that triggers your server’s 400

Try these variants against your TensorRT endpoint and see if any 400:

D) No max_tokens (some servers require it)

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":"hi"}]}' | head -200

E) Multipart message content (OpenAI allows content as an array of parts; lots of “compatible” servers don’t)

#
curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":[{"type":"text","text":"hi"}]}],"max_tokens":32}' | head -200

F) stream_options (newer OpenAI field; many servers 400 on it)

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":"hi"}],"max_tokens":32,"stream":true,"stream_options":{"include_usage":true}}' | head -80

G) response_format (compaction/structured steps often use this; many servers 400)

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
#
-H 'Content-Type: application/json' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":"hi"}],"max_tokens":32,"response_format":{"type":"json_object"}}' | head -200

Whichever one fails first is very likely what OpenClaw is doing differently.

Step 2: quick OpenClaw-side test for “request too big / too many tools”

Even though your server supports tools, it might choke on the huge tool schema set OpenClaw sends.

Temporarily set a tiny tool set:

// ~/.openclaw/openclaw.json
{
tools: { profile: "minimal" }, // sends almost no tools to the model
#
}

Then try Control UI chat again. If it suddenly works, your server is basically saying “fine with tools, but not with that many / that big”.

Docs on tool limiting: https://docs.openclaw.ai/tools

Signal config bug in your snippet

Yes: allowFrom must be strings, and Signal numbers should be E.164 with the +.

So this is wrong (number literal):

allowFrom: [ 1yyyyyyyyyy ]

This is right:

#
allowFrom: ["+1yyyyyyyyyy"]

Also: if you’re debugging, I’d switch Signal to pairing mode first (it avoids formatting surprises and will tell you what sender id it’s seeing):
https://docs.openclaw.ai/channels/signal


If you paste which of D/E/F/G fails (or if all pass), we’ll know exactly what OpenClaw is sending that TensorRT-LLM doesn’t like.

last arrow
#

they all pass... lol
adding the tools property to the config did not magically make anything work, the chat tab still fails with the same 400 and trying to compact session

stuck zephyrBOT
#

Okay that’s actually excellent news: your TensorRT endpoint can do tools, and it can do them with OpenAI-ish shapes. So the “400 (no body)” from OpenClaw is almost certainly one of:

  1. Headers/auth difference (OpenClaw sends Authorization: Bearer 
; your curl didn’t)
  2. A specific field OpenClaw includes that we haven’t hit yet (common: tool_choice as an object, parallel_tool_calls, assistant content: null, tool result messages with role:"tool", or response_format json_schema style)

Let’s pin it down with 2 very targeted curls.

A) Does your server choke on Authorization header?

(OpenClaw will send this if you set apiKey.)

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer totally-not-a-real-key' \
-d '{"model":"Qwen3-Next","messages":[{"role":"user","content":"hi"}],"max_tokens":32}' | head -120
#
  • If this 400s: fix is to stop sending auth headers from OpenClaw (or set the exact key the server expects).
  • In OpenClaw custom providers there’s an authHeader toggle (see config examples: https://docs.openclaw.ai/gateway/configuration-examples). Try setting authHeader: false for that provider.

B) Does it choke on actual tool-call transcripts (role:tool, content:null)?

This is the most common “tools work but real agents fail” trap.

curl -sS -D- http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model":"Qwen3-Next",
"max_tokens":64,
"tools":[{"type":"function","function":{"name":"noop","description":"noop","parameters":{"type":"object","properties":{},"additionalProperties":false}}}],
"messages":[
{"role":"user","content":"Call noop then say hi"},
{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"noop","arguments":"{}"}}]},
#
{"role":"tool","tool_call_id":"call_1","content":"{}"}
]
}' | head -200
  • If this 400s: your server supports tools declaration, but not the follow-up tool_calls / role:"tool" message protocol OpenClaw relies on.

If both A and B pass



then we need to see the exact JSON OpenClaw sends.

Fastest way: run a tiny local “dump proxy” in front of TensorRT-LLM and point OpenClaw at it:

  1. Create ~/dump_proxy.py:
from fastapi import FastAPI, Request, Response
#
import httpx

app = FastAPI()
client = httpx.AsyncClient(base_url="http://127.0.0.1:8000")

@app.api_route("/{path:path}", methods=["GET","POST","PUT","PATCH","DELETE"])
async def proxy(path: str, req: Request):
body = await req.body()
print("\n=== IN ===", req.method, "/", path)
print(body.decode("utf-8", errors="replace")[:20000])

upstream = await client.request(
req.method,
f"/{path}",
content=body,
#
headers={k:v for k,v in req.headers.items() if k.lower() != "host"},
)
print("=== OUT ===", upstream.status_code)
print(upstream.text[:20000])
return Response(content=upstream.content, status_code=upstream.status_code, headers=dict(upstream.headers))
  1. Run it:
pip install fastapi uvicorn httpx
uvicorn dump_proxy:app --host 127.0.0.1 --port 8001
  1. Change your OpenClaw provider baseUrl from http://127.0.0.1:8000/v1 to:
    http://127.0.0.1:8001/v1
#

Then retry Control UI chat once and paste what the proxy prints (it’ll show the exact request + the actual 400 response body if there is one).


Signal config: yes, you found a bug

allowFrom must be strings, and phone numbers should be E.164 (with the +).

So:

allowFrom: ["+1yyyyyyyyyy"]

not:

allowFrom: [1yyyyyyyyyy]

Signal docs example: https://docs.openclaw.ai/channels/signal

#

Send back results for curl A + curl B (just status + body), and we’ll know which branch you’re on in under a minute.

last arrow
#

A: works (my endpoint doesn't require auth, I set the apiKey to tensorrt_llm since that was in the example, but it should be ignored) Also, I did not change the 'Authorization: Bearer totally-not-a-real-key' that was sent as is, which tells me it does in fact ignore the apikey
B: also works

the proxy outputs:
tons of stuff.../.openclaw/workspace/USER.md\n# USER.md - About Your Human\n\n_Learn about the person you're helping. Update this as you go._\n\n- Name:\n- What to call them:\n- Pronouns: (optional)\n- Timezone:\n- Notes:\n\n## Context
=== OUT === 400
{"object":"error","message":"[{'type': 'extra_forbidden', 'loc': ('body', 'tools', 0, 'function', 'strict'), 'msg': 'Extra inputs are not permitted', 'input': False}, {'type': 'extra_forbidden', 'loc': ('body', 'store'), 'msg': 'Extra inputs are not permitted', 'input': False}]","type":"BadRequestError","param":null,"code":400}
INFO: 127.0.0.1:60990 - "POST /v1/chat/completions HTTP/1.1" 400 Bad Request

(I fixed the signal config, still doesn't hit the server - Signal has never been able to reach the server)

stuck zephyrBOT
#

The proxy output is the key. Your TensorRT-LLM OpenAI server is running in “forbid unknown fields” mode, and OpenClaw is sending two fields it doesn’t accept:

  • store: false (top-level)
  • tools[0].function.strict: false

So it’s not “tools don’t work” — it’s “this server rejects extra keys in the request JSON”.

You can fix this cleanly by adding a compat override on that model so OpenClaw omits those fields.

Fix: add compat flags to your custom model entry

In the same place you defined the model (your models.json / provider block), add:

{
"models": {
"providers": {
#
"custom-127-0-0-1-8000": {
"baseUrl": "http://127.0.0.1:8000/v1",
"api": "openai-completions",
"models": [
{
"id": "Qwen3-Next",
"name": "Qwen3-Next (Custom Provider)",
"compat": {
"supportsStrictMode": false,
"supportsStore": false
}
}
]
}
}
#
}
}

This is an upstream-known issue pattern (example config is in OpenClaw issue #6674): https://github.com/openclaw/openclaw/issues/6674

After editing, restart the gateway to be sure it reloads:

openclaw gateway restart

Then try Control UI chat again — you should stop seeing that 400.

If you want to verify immediately

Re-run your dump proxy after the change: the 400 should disappear, and you should no longer see store or function.strict in the forwarded JSON.

#

Signal note

Good catch on allowFrom: it must be a string and in E.164 format (with +). If Signal still “doesn’t hit the server”, once the model 400s are fixed, run:

openclaw channels status --probe
openclaw logs --follow

and send a DM to the bot number — the logs will usually say whether it’s blocked by allowlist/pairing vs signal-cli transport not receiving events.

last arrow
#

The 400s disappeared so far, the chat returned a response... but now my real troubles might have begun... đŸ€Ł
Hey. I just came online. Who are you? And who am I?

Assistant
3:53 PM
U
Fantastic! I am Chris. You are my AI assistant; I haven't settled on a name for you yet, maybe you can help me out with that after we get to know each other a little bit better.

You
3:57 PM
A

<tool_call> {"name": "session_status", "arguments": {}} </tool_call>
Assistant
3:57 PM
uhhhhmmmmm, nice tool call?
gonna poke at the signal stuff for a minute lol

stuck zephyrBOT
#

Nice — that proxy error was exactly the culprit, and the fact the 400s are gone + Control UI chat responded means the Gateway↔model path is finally healthy.

Why it now “thinks you’re Chris” / weird vibe

That’s just the model guessing because your workspace bootstrap files (USER.md etc) are basically empty templates. OpenClaw is literally sending them (you saw ~/.openclaw/workspace/USER.md in the proxy dump), so if Name: is blank, the model invents one.

Fix: edit ~/.openclaw/workspace/USER.md and fill in at least your name + what to call you. Optionally also set identity.name in openclaw.json so the assistant has a stable name. (This is normal; nothing “broken” here.)

The <tool_call> 
 session_status 
 thing

That line is not OpenClaw successfully running a tool — it’s your model emitting “tool call looking text” in-band, then reacting to it. Many “OpenAI compatible” servers accept tools fine, but the underlying model still isn’t great at actually using tools in the intended way.

Now that we’ve fixed the schema strictness (store + strict), tool calling may still be “meh” depending on the model. If you want, the quickest sanity check is: ask it something that should obviously use tools (e.g. “list the last 5 sessions” / “what’s my gateway status”) and see whether OpenClaw shows real tool cards/results, not XML-ish text. If it only prints <tool_call> blocks, that’s model behavior, not your install.

(If you want real-time recommendations on tool-capable models, ask in #models; my list will go stale instantly.)

Signal: if it “never hits the server”, switch to pairing temporarily

Even with allowFrom fixed, Signal often identifies senders by UUID (uuid:...), not reliably by phone number. Easiest path to get unblocked:

#
  1. Set:
channels: {
signal: {
dmPolicy: "pairing",
// (you can remove allowFrom while debugging)
}
}
  1. Restart gateway, then DM the bot number.

  2. On the WSL box:

openclaw pairing list signal
openclaw pairing approve signal <CODE>
#
openclaw channels status --probe
openclaw logs --follow

If you paste the channels status --probe output + the log lines right after you send a DM, we can tell if it’s:

  • signal-cli not receiving events at all, vs
  • OpenClaw receiving but blocking due to policy/identifier mismatch.

Also: be careful pasting proxy dumps into Discord — they include your local files by design.

last arrow
#

I did not convey that first conversation adequately:

Me: Hello
Assistant: Hey. I just came online. Who are you? And who am I?
Me: Fantastic! I am Chris. You are my AI assistant; I haven't settled on a name for you yet, maybe you can help me out with that after we get to know each other a little bit better.
Assistant: <tool_call> {"name": "session_status", "arguments": {}} </tool_call>

that is why I said nice tool call, because it in fact was not, not good at all lol
but that is the model's fault, it is an NVFP4 quant of Qwen3-Next-80B, I was playing with this model because you can get it to do things it says it won't do lol, just testing 😉

The signal stuff is fixed, such a flaky setup, switching to pairing, DM, then approving worked, worked, now I'm kind of afraid to touch it and go back to allowFrom lol

Thank you for your help, way better than usual when going through this kind of thing with an assistant! Well done!

stuck zephyrBOT
#

Yep, that transcript makes total sense now: the model decided to emit a fake tool call instead of answering. OpenClaw can only execute tools when it’s using a provider/model that actually follows the tool-calling protocol reliably — so with a “chaos” quant like that, you’ll see goofy <tool_call> text sometimes.

Glad the big blocker is gone though: compat.supportsStrictMode=false + compat.supportsStore=false was the real “why won’t it even hello world” issue for strict OpenAI-compatible endpoints.

On Signal: staying on dmPolicy: "pairing" is honestly the least painful option. allowFrom is fine once you’re sure what identifier Signal is surfacing (often uuid:...), but if it’s flaky for you, pairing is the right “don’t touch it” setting.

If this thread solved it, please right-click the message with the compat fix → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person who hits the strict/store extra_forbidden 400.