2026 OpenClaw chat works but tools don't: tools.profile matrix, tools.deny & agent override triage runbook

About 18 min read · MACCOME

If you just upgraded OpenClaw or changed config and now see Telegram/Slack chat working while exec, read, write, or browser report unavailable—or the Agent prints tool-call text without executing, this article answers: which layer to check first for three symptom classes; how the tools.profile four-way matrix lines up with tools.deny and agent overrides; and a six-step reproducible runbook with a verification ladder. It complements the Gateway no-reply and model-error guide—that article owns channels and models; this one owns the tool allowlist contract.

Six common root causes when chat works but tools do not (triage before you edit config)

  1. tools.profile stuck on messaging or minimal: an upgrade or wizard defaulted to a narrower tool surface—sessions feel fine, then exec returns not found.
  2. tools.deny collateral damage: compliance temporarily denied exec or browser and the rule outlived the change ticket.
  3. agents.list[].tools.profile overrides global: you changed global settings but the active agent still inherits a narrower profile.
  4. Half-upgrade without Gateway reload: the CLI reads new config while the Gateway process still runs the old allowlist—same split-brain class as the bad-release rollback article, though you may not need to roll the image back.
  5. Model lacks reliable tool-calling: weak models emit tool calls as plain text; profile changes will not help—switch models or reduce task complexity.
  6. Confusing channel no-reply with tool failure: run the no-reply triage first so you do not spin on the allowlist layer.

OpenClaw's tool surface is not "install and everything is on." The effective set is the intersection of global profile, deny list, and agent-level overrides. 2026 upstream docs define tools.profile as the baseline allowlist: minimal keeps lightweight session state; messaging skews to channels and sessions; coding covers filesystem, runtime, web, sessions, memory, and other engineering tools; full applies no extra profile-level restriction. Many teams first hit this after an upgrade not because the Gateway died, but because the contract tightened from implicit allow to explicit permit while the change ticket never said "restart plus minimal probe." On-call then burns a release window retrying the same prompt in chat.

If the Gateway runs on a sleeping laptop, you may also see "config changed but launchd/container never reloaded." Hosting the authoritative Gateway on an always-on, dedicated remote Mac you can ticket, then reaching Control UI via SSH local forward, separates the configuration plane from terminal noise. The verification ladder below stresses acceptance on the Gateway side, not CLI success text alone.

What you see Suspect layer first First action (executable)
Replies work; exec/read report tool not found tools.profile too narrow or agent override Export effective profile; if needed openclaw config set tools.profile coding; then gateway restart
One tool always dead, others fine tools.deny Search config for deny rules; compare with official tools docs and remove misfires
Only one agent fails agents.list[].tools.profile Align that agent's profile with global; avoid "changed A, tested B"
JSON-shaped tool-call text in messages Model tool-calling capability Switch to a model with function calling; reduce parallel tools for A/B
Channel fully silent Channel / token / model routing Jump to the Gateway no-reply article; defer this runbook

tools.profile four-way matrix: coding or full?

In practice most automation and engineering agents should land on coding: file I/O, shell, web fetch, sessions, and memory, with an easier security review than full. Use full only when you explicitly need no profile-level trimming and already have auditing. messaging suits pure relay/customer-service flows; minimal when you only want state, not filesystem or shell. Read alongside Agents / Skills / memory_search tuning and put "tool surface" and "context limits" on the same change ticket—otherwise memory search works while read is blocked by profile.

At runtime the Gateway resolves an effective tool registry at session start and hands it to the model for tool-calling. If exec is not registered, the runtime rejects the call—or weak models print the intent as text. That is why post-upgrade "chat only" threads usually end on profile or deny, not channel tokens—but triage order still excludes no-reply before this article so you do not waste time on the wrong layer.

profile value Typical capabilities (illustrative) When to use
minimal Lightweight state such as session_status Read-only monitoring; no files or shell
messaging Channel and session management tools Relay/support only; no code or file ops
coding filesystem, runtime, web, sessions, memory, media, etc. Engineering automation, scripts, repos (recommended default)
full No extra profile-layer trimming Production exceptions with audit and least exposure
info

Tip: after changing tools.profile you must restart the Gateway (local daemon, Docker Compose, or remote launchd unit). openclaw doctor alone does not guarantee the running process loads the new allowlist. For Docker, follow the reload order in the production runbook.

tools.deny and agent overrides: three-layer check order

Use a fixed order so on-call does not hop layers: read the running Gateway's effective profile (or equivalent export) → inspect tools.deny → inspect the current agent's agents.list[].tools.profile → only then change global config. If you just ran a release-channel upgrade, confirm on the ticket whether a default profile migration shipped; if you need to roll the image back, use the bad-release rollback instead of endless profile guessing.

In multi-agent teams the classic incident is "global is coding but production bot still binds messaging on the agent row." Tickets should record agent name under test and trigger channel, and acceptance should run the minimal probe on both CLI chat and Telegram/Slack—routing can differ. If deny rules came from a security hardening, log expiry and owner; three months later nobody remembers why browser is blocked.

Six-step runbook: align profile, restart, probe acceptance

  1. Freeze evidence: save openclaw --version, current tools.profile, agent list summary, and a failed conversation request id if you have one.
  2. Classify symptoms: use the table above for profile, deny, agent, or model; if the symptom is no reply at all, stop this runbook.
  3. Set target profile: engineering automation defaults to coding; document rationale and rollback value on the ticket before editing.
  4. Apply config and restart Gateway: locally openclaw gateway restart; on Docker use docker compose restart or equivalent—ensure one authoritative Gateway.
  5. Verification ladder: openclaw doctoropenclaw gateway status → minimal non-destructive probe (read-only read or small exec echo) → if channels are wired, channels status --probe.
  6. Leave traces and prevent recurrence: write post-upgrade default profile into ROLLBACK.md / internal runbook; tie to pinning matrix so the next upgrade does not silently tighten again.
bash
# Evidence and alignment (fields vary by environment)
openclaw --version
openclaw config get tools.profile 2>/dev/null || true

# Common fix path (back up config before editing)
openclaw config set tools.profile coding
openclaw gateway restart

openclaw doctor
openclaw gateway status
# Minimal probe: trigger one read-only read or harmless exec in Control UI or CLI

Three metrics worth pasting into the on-call handbook

  • "Chat-only" mis-triage rate: among weekly "tools broken" tickets, the share whose root cause was tools.profile, deny, or agent override; if above 40% for two weeks, upgrades lack profile acceptance.
  • Minutes from profile change to green probe: small teams should target median ≤10; if often >30, Gateway reload paths are inconsistent or you run dual Gateways (Docker plus local).
  • Post-restart failure rate that escalates to rollback: if >15%, parallel-check model capability and version regression instead of stacking profile changes.

These metrics separate "can chat" from "can run tools" as observable events. They also apply to always-on remote Gateways: when builds and agents share a multi-region node, avoid change windows at disk/CPU peaks or probe failures look like profile bugs.

From a FinOps angle, teams rent short-term nodes to "try OpenClaw" then discover the tool surface was tightened on the last day of the lease. Safer: on POC day one, list target profile, empty deny set, and agent override policy beside POC scale-up KPI matrix "day-one green build / green Gateway"—do not treat the Agent as a chat toy with a separate acceptance bar.

Close: treat the allowlist as engineering, not a mystery switch

Retrying prompts in chat or editing config without restart might occasionally work, but it is not auditable, not reproducible on a second machine, and you cannot explain actual tool permissions to security. By contrast, a Gateway on an always-on, dedicated, ticketed remote Mac with documented default profiles and a verification ladder compresses MTTR from "an evening of prompts" to "ten minutes with a paper trail."

If you still chase releases on a laptop, budget for sleep-induced Gateway stalls, lid-close reload gaps, and verbal profile drift across teammates. For 7×24, auditable production Agents aligned with team CI cadence, hosting on MACCOME Mac mini (M4 / M4 Pro) with flexible multi-region leases usually beats fighting power policy on personal hardware. Start from the multi-region node and lease guide, then wire topology with the SSH forward runbook.

FAQ

After an upgrade, must I set tools.profile to full?

No. coding covers most engineering automation; use full with auditing. Always restart and run a minimal probe. For a production-dedicated host see Mac mini rental rates and cloud Mac support help.

Does this overlap with the Gateway no-reply article?

The no-reply guide owns channels, models, and handshakes; this one owns the allowlist stack. If there is zero reply, start there; if only tools return not found, run this runbook.

Still seeing tool-call text after a profile change?

A/B with a model that supports reliable function calling first; if only one channel misbehaves, check channel docs. After ruling out half-upgrade, consider version rollback.