OpenClaw FAQ: Setup, Configuration, and Troubleshooting
Answers to frequently asked questions about OpenClaw setup, configuration, and usage. Includes quick diagnostics, health probes, and log tailing for local and production deployments.
Read this when
- Answering common setup, install, onboarding, or runtime support questions
- Triaging user-reported issues before deeper debugging
Here are the quick answers and more detailed fixes for real-world deployments (local development, VPS, multi-agent setups, OAuth/API keys, model failover). For runtime diagnostics, refer to Troubleshooting. The complete configuration guide is at Configuration.
First 60 seconds if something is broken
Quick status
openclaw status
Fast local summary: check the OS and updates, gateway and service reachability, agents and sessions, plus provider configuration and runtime issues (when the gateway is reachable).
Pasteable report (safe to share)
openclaw status --all
Read-only diagnosis that tails logs with tokens redacted.
Daemon + port state
openclaw gateway status
Shows supervisor runtime status versus RPC reachability, the probe target URL, and which configuration the service likely used.
Deep probes
openclaw status --deep
A live health probe for the gateway, including channel probes when supported (requires a reachable gateway). See Health.
Tail the latest log
openclaw logs --follow
If RPC is unavailable, fall back to:
tail -f "/tmp/openclaw/openclaw-$(date +%F).log"
# Named profile example:
tail -f "/tmp/openclaw/openclaw-dev-$(date +%F).log"
File logs are separate from service logs; consult Logging and Troubleshooting.
Run the doctor (repairs)
openclaw doctor
Repairs or migrates configuration and state, then runs health checks. See Doctor.
Gateway snapshot (WS-only)
openclaw health --json
openclaw health --verbose # shows the target URL + config path on errors
Requests a complete snapshot from the running gateway. See Health.
Quick start and first-run setup
Questions about first-run steps (install, onboarding, auth routes, subscriptions, initial failures) are answered in the First-run FAQ.
What is OpenClaw?
What is OpenClaw, in one paragraph?
OpenClaw is a personal AI assistant you operate on your own hardware. It responds through the messaging platforms you already use (Discord, Google Chat, iMessage, Mattermost, Signal, Slack, Telegram, WebChat, WhatsApp, and bundled channel plugins such as QQ Bot) and supports voice plus a live Canvas on supported platforms. The Gateway is the always-on control plane; the assistant itself is the product.
Value proposition
OpenClaw is not "just a Claude wrapper." It is a local-first control plane that runs a capable assistant on your own hardware, reachable from the chat apps you already use, with stateful sessions, memory, and tools, without handing your workflows to a hosted SaaS.
- Your devices, your data: run the Gateway wherever you want (Mac, Linux, VPS) and keep the workspace and session history local.
- Real channels, not a web sandbox: Discord/iMessage/Signal/Slack/Telegram/WhatsApp/etc, plus mobile voice and Canvas on supported platforms.
- Model-agnostic: use Anthropic, MiniMax, OpenAI, OpenRouter, etc., with per-agent routing and failover.
- Local-only option: run local models so all data can stay on your device.
- Multi-agent routing: separate agents per channel, account, or task, each with its own workspace and defaults.
- Open source and hackable: inspect, extend, and self-host without vendor lock-in.
Docs: Gateway, Channels, Multi-agent, Memory.
I just set it up - what should I do first?
Good first projects: build a website (WordPress, Shopify, or a static site); prototype a mobile app (outline, screens, API plan); organize files and folders; connect Gmail and automate summaries or follow-ups.
It can handle large tasks, but works best split into phases with sub-agents for parallel work.
What are the top five everyday use cases for OpenClaw?
- Personal briefings: summaries of inbox, calendar, and news you care about.
- Research and drafting: quick research, summaries, and first drafts for emails or docs.
- Reminders and follow-ups: cron- or heartbeat-driven nudges and checklists.
- Browser automation: filling forms, collecting data, repeating web tasks.
- Cross-device coordination: send a task from your phone, let the Gateway run it on a server, get the result back in chat.
Can OpenClaw help with lead gen, outreach, ads, and blogs for a SaaS?
Yes, for research, qualification, and drafting: scanning sites, building shortlists, summarizing prospects, writing outreach or ad copy drafts.
For outreach or ad runs, keep a human in the loop. Avoid spam, follow local laws and platform policies, and review anything before it sends. Let OpenClaw draft; you approve.
Docs: Security.
What are the advantages vs Claude Code for web development?
OpenClaw is a personal assistant and coordination layer, not an IDE replacement. Use Claude Code or Codex for the fastest direct coding loop inside a repo. Use OpenClaw for durable memory, cross-device access, and tool orchestration.
- Persistent memory and workspace across sessions.
- Multi-platform access (Telegram, WhatsApp, TUI, WebChat).
- Tool orchestration (browser, files, scheduling, hooks).
- Always-on Gateway (run on a VPS, interact from anywhere).
- Nodes for local browser/screen/camera/exec.
Showcase: https://openclaw.ai/showcase.
Skills and automation
How do I customize skills without keeping the repo dirty?
Use managed overrides instead of editing the repo copy. Put changes in ~/.openclaw/skills/<name>/SKILL.md (or add a folder via skills.load.extraDirs in ~/.openclaw/openclaw.json). Precedence: <workspace>/skills -> <workspace>/.agents/skills -> ~/.agents/skills -> ~/.openclaw/skills -> bundled -> skills.load.extraDirs, so managed overrides win over bundled skills without touching git. To install globally but limit visibility to some agents, keep the shared copy in ~/.openclaw/skills and control visibility with agents.defaults.skills / agents.entries.*.skills. Only upstream-worthy edits should go out as PRs against the repo copy.
Can I load skills from a custom folder?
Yes: add directories via skills.load.extraDirs in ~/.openclaw/openclaw.json (lowest precedence in the order above). clawhub installs into ./skills by default, which OpenClaw treats as <workspace>/skills on the next session. To limit visibility to certain agents, pair with agents.defaults.skills or agents.entries.*.skills.
How can I use different models or settings for different tasks?
Supported patterns:
- Cron jobs: a
modeloverride can be assigned per individual isolated job. - Agents: tasks can be sent to separate agents, each with its own default model, thinking level, and streaming parameters.
- On-demand switch: the current session model can be changed at any time using
/model.
Example - identical model, different agent-level configurations:
{
agents: {
list: [
{
id: "coder",
model: "xiaomi/mimo-v2.5-pro",
thinkingDefault: "high",
params: { temperature: 0.1 },
},
{
id: "chat",
model: "xiaomi/mimo-v2.5-pro",
thinkingDefault: "off",
params: { temperature: 0.8 },
},
],
},
}
Place shared per-model defaults inside agents.defaults.models["provider/model"].params, then put agent-specific overrides in flat agents.entries.*.params. Do not repeat the same model under nested agents.entries.*.models["provider/model"].params; that location is meant for per-agent model catalogs and runtime overrides.
Refer to Cron jobs, Multi-Agent Routing, Configuration, and Slash commands.
The bot freezes while doing heavy work. How do I offload that?
For long or parallel work, use sub-agents: they operate in their own session, return a summary, and keep your primary chat responsive. Ask the bot to "spawn a sub-agent for this task," or use /subagents. To check whether the Gateway is busy, use /status.
Both long tasks and sub-agents consume tokens. If cost is a concern, set a cheaper model for sub-agents through agents.defaults.subagents.model.
Documentation: Sub-agents, Background Tasks.
How do thread-bound subagent sessions work on Discord?
Bind a Discord thread to a subagent or session target so subsequent messages in that thread remain tied to that bound session.
- Spawn using
sessions_spawnwiththread: true(optionallymode: "session"for persistent follow-up). - Alternatively, bind manually with
/focus <target>. - Use
/agentsto inspect the binding state. /session idle <duration|off>and/session max-age <duration|off>control automatic unfocusing./unfocusdetaches the thread.
Configuration: session.threadBindings.enabled (global toggle), session.threadBindings.idleHours (default 24, 0 disables), session.threadBindings.maxAgeHours (default 0 means no hard cap), and session.threadBindings.spawnSessions for auto-bind on spawn (default true).
Documentation: Sub-agents, Discord, Configuration Reference, Slash commands.
A subagent finished, but the completion update went to the wrong place or never posted. What should I check?
Examine the resolved requester route:
- In completion-mode subagent delivery, a bound thread or conversation route is preferred when one exists.
- If the completion origin provides only a channel, OpenClaw falls back to the stored route from the requester session (
lastChannel/lastTo/lastAccountId), allowing direct delivery to still succeed. - Without a bound route or usable stored route, direct delivery may fail, and the result falls back to queued session delivery instead of posting immediately.
- Invalid or outdated targets can also trigger queue fallback or cause final delivery to fail.
- If the child's last visible assistant reply is exactly
NO_REPLY/no_replyorANNOUNCE_SKIP, OpenClaw intentionally suppresses the announcement rather than posting stale earlier progress.
Debugging: openclaw tasks show <lookup> where <lookup> is a task id, run id, or session key.
Documentation: Sub-agents, Background Tasks, Session Tools.
Cron or reminders do not fire. What should I check?
Cron executes within the Gateway process; it will not run if the Gateway is not continuously active.
- Verify that cron is enabled (
cron.enabled) andOPENCLAW_SKIP_CRONis not set. - Ensure the Gateway runs 24/7 (no sleep or restarts).
- Check the job timezone (
--tzagainst the host timezone).
Debugging:
openclaw cron run <jobId>
openclaw cron runs --id <jobId> --limit 50
Documentation: Cron jobs, Automation.
Cron fired, but nothing was sent to the channel. Why?
Review the delivery mode:
--no-deliver/delivery.mode: "none": no runner fallback delivery is anticipated.- Announce target is missing or invalid (
channel/to): the runner did not perform outbound delivery. - Channel authentication failures (
unauthorized,Forbidden): the runner attempted delivery but credentials prevented it. - A silent isolated result (
NO_REPLY/no_replyonly) is regarded as deliberately non-deliverable, so queued fallback delivery is also blocked.
For isolated cron jobs, the agent can still send directly via the message tool if a chat route is available. --announce only governs runner fallback delivery for final text the agent has not already sent on its own.
Debug:
openclaw cron runs --id <jobId> --limit 50
openclaw tasks show <lookup>
Docs: Cron jobs, Background Tasks.
Why did an isolated cron run switch models or retry once?
This is the live model-switch mechanism, not duplicate scheduling. Isolated cron stores a runtime model handoff and retries when the active run throws LiveSessionModelSwitchError, preserving the switched provider/model (and any switched auth-profile override) before retrying.
Model-selection order: Gmail hook model override (hooks.gmail.model) first, then per-job model, then any stored cron-session model override, then normal agent/default model selection.
The retry loop is capped at the initial attempt plus 2 switch retries; cron then stops instead of looping indefinitely.
Debug:
openclaw cron runs --id <jobId> --limit 50
How do I install skills on Linux?
Use native openclaw skills commands or place skills into your workspace; the macOS Skills UI is not available on Linux. Browse skills at https://clawhub.ai.
openclaw skills search "calendar"
openclaw skills search --limit 20
openclaw skills install @owner/<skill-slug>
openclaw skills install @owner/<skill-slug> --version <version>
openclaw skills install @owner/<skill-slug> --force
openclaw skills install @owner/<skill-slug> --global
openclaw skills update --all
openclaw skills update --all --global
openclaw skills list --eligible
openclaw skills check
Native openclaw skills install writes into the active workspace skills/ directory by default. Add --global to install into the shared managed skills directory for all local agents. Install the separate clawhub CLI only to publish or sync your own skills. Use agents.defaults.skills or agents.entries.*.skills to restrict which agents see shared skills.
Can OpenClaw run tasks on a schedule or continuously in the background?
Yes, through the Gateway scheduler:
- Cron jobs for scheduled or recurring tasks (persist across restarts).
- Heartbeat for main-session periodic checks.
- Isolated jobs for autonomous agents that post summaries or deliver to chats.
Docs: Cron jobs, Automation, Heartbeat.
Can I run Apple macOS-only skills from Linux?
Not directly. macOS skills are gated by metadata.openclaw.os plus required binaries, and only load when eligible on the Gateway host. On Linux, darwin-only skills (apple-notes, apple-reminders, things-mac) will not load unless you override the gating.
Three supported patterns:
Option A - run the Gateway on a Mac (simplest). Run the Gateway where the macOS binaries exist, then connect from Linux in remote mode or over Tailscale. Skills load normally because the Gateway host is macOS.
Option B - use a macOS node (no SSH). Run the Gateway on Linux, pair a macOS node (menubar app), and set Node Run Commands to "Always Ask" or "Always Allow" on the Mac. OpenClaw treats macOS-only skills as eligible when required binaries exist on the node; the agent runs them via the nodes tool. With "Always Ask," approving "Always Allow" in the prompt adds that command to the allowlist.
Option C - proxy macOS binaries over SSH (advanced). Keep the Gateway on Linux, but make the required CLI binaries resolve to SSH wrappers that run on a Mac, then override the skill to allow Linux so it stays eligible.
- Create an SSH wrapper for the binary (example:
memofor Apple Notes):#!/usr/bin/env bash set -euo pipefail exec ssh -T user@mac-host /opt/homebrew/bin/memo "$@" - Put the wrapper on
PATHon the Linux host (for example~/bin/memo). - Override the skill metadata (workspace or
~/.openclaw/skills) to allow Linux:--- name: apple-notes description: Manage Apple Notes via the memo CLI on macOS. metadata: { "openclaw": { "os": ["darwin", "linux"], "requires": { "bins": ["memo"] } } } --- - Start a new session so the skills snapshot refreshes.
Do you have a Notion or HeyGen integration?
Not built in today. Options:
- Custom skill / plugin: best for reliable API access (both have APIs).
- Browser automation: works without code but is slower and more fragile.
For agency-style per-client context: keep one Notion page per client (context + preferences + active work) and ask the agent to fetch that page at the start of a session.
For a native integration, open a feature request or build a skill against those APIs.
openclaw skills install @owner/<skill-slug>
openclaw skills update --all
Native installs land in the active workspace skills/ directory; use --global for all local agents, or configure agents.defaults.skills / agents.entries.*.skills to limit visibility. Some skills expect Homebrew-installed binaries; on Linux that means Linuxbrew.
See Skills, Skills config, ClawHub.
How do I use my existing signed-in Chrome with OpenClaw?
Use the built-in user browser profile, which attaches through Chrome DevTools MCP:
openclaw browser --browser-profile user tabs
openclaw browser --browser-profile user snapshot
To assign a custom name, define an explicit MCP profile:
openclaw browser create-profile --name chrome-live --driver existing-session
openclaw browser --browser-profile chrome-live tabs
That profile can operate with either the local host browser or a connected browser node. When the Gateway is on a different machine, either run a node host on the browser machine or switch to remote CDP.
Current restrictions on existing-session / user profiles compared to the managed openclaw profile:
click,type,hover,scrollIntoView,drag, andselectdepend on snapshot refs rather than CSS selectors.- Upload hooks accept
reforinputRef, one file at a time, and do not support CSSelement. responsebody, PDF export, download interception, and batch actions continue to need the managed browser path.
For a detailed comparison, visit Browser.
Sandboxing and memory
Is there a dedicated sandboxing doc?
Yes: refer to Sandboxing. For Docker instructions (full gateway inside Docker or sandbox images), see Docker.
Docker feels limited - how do I enable full features?
The default image prioritizes security and runs as the node user, meaning system packages, Homebrew, and bundled browsers are omitted. To create a more complete environment:
- Use
OPENCLAW_HOME_VOLUMEto persist/home/node, ensuring caches survive restarts. - Add system dependencies into the image via
OPENCLAW_IMAGE_APT_PACKAGES. - Install Playwright browsers using the bundled CLI:
node /app/node_modules/playwright-core/cli.js install chromium. - Configure
PLAYWRIGHT_BROWSERS_PATHand persist that location.
Documentation: Docker, Browser.
Can I keep DMs personal but make groups public/sandboxed with one agent?
Yes, when private traffic consists of DMs and public traffic consists of groups. Set agents.defaults.sandbox.mode: "non-main" so group and channel sessions (non-main keys) use the configured sandbox backend while the main DM session remains on the host. Once sandboxing is enabled, Docker becomes the default backend. Limit the tools available inside sandboxed sessions with tools.sandbox.tools.
Setup guide: Groups: personal DMs + public groups. Key reference: Gateway configuration.
How do I bind a host folder into the sandbox?
Configure agents.defaults.sandbox.docker.binds to ["host:container:mode"] (for instance "/home/user/src:/src:ro"). Global and per-agent binds merge together; per-agent binds are ignored when scope: "shared" is active. Use :ro for anything sensitive, as binds bypass the sandbox filesystem walls.
OpenClaw validates bind sources against both the normalized path and the canonical path resolved through the deepest existing ancestor, so symlink-parent escapes fail closed even when the final path segment does not yet exist.
See Sandboxing and Sandbox vs Tool Policy vs Elevated.
How does memory work?
OpenClaw memory consists of Markdown files in the agent workspace: daily notes go in memory/YYYY-MM-DD.md, and curated long-term notes go in MEMORY.md (main and private sessions only).
OpenClaw also performs a silent pre-compaction memory flush before compaction summarizes the conversation, prompting the model to write durable notes first. This flush only occurs when the workspace is writable (read-only sandboxes skip it); disable it with agents.defaults.compaction.memoryFlush.enabled: false. See Memory.
Memory keeps forgetting things. How do I make it stick?
Ask the bot to write the fact to memory: long-term notes belong in MEMORY.md, short-term context in memory/YYYY-MM-DD.md. Reminding the model to store memories usually fixes the issue. If it continues to forget, confirm the Gateway uses the same workspace on every run.
Documentation: Memory, Agent workspace.
Does memory persist forever? What are the limits?
Memory files reside on disk and persist until removed; the only limit is your storage capacity, not the model. Session context remains constrained by the model context window, so long conversations may compact or truncate. That is why memory search exists, pulling only the relevant parts back into context.
Documentation: Memory, Context.
Does semantic memory search require an OpenAI API key?
Only when you use OpenAI embeddings, which is the default provider. Codex OAuth covers chat and completions but does not grant embeddings access, so signing in with Codex (OAuth or the Codex CLI login) does not enable semantic memory search. OpenAI embeddings still require a real API key (OPENAI_API_KEY or models.providers.openai.apiKey).
To operate only on your local machine, set memory.search.provider: "local" (for GGUF/llama.cpp). Alternative supported providers include Bedrock, DeepInfra, Gemini (via GEMINI_API_KEY or memory.search.remote.apiKey), GitHub Copilot, LM Studio, Mistral, Ollama, any OpenAI-compatible endpoint, and Voyage. For configuration guidance, refer to Memory and Memory search.
Where things live on disk
Is all data used with OpenClaw saved locally?
Not exactly: OpenClaw's own state remains on your machine, but external services still receive whatever you transmit to them.
- Local as the default: sessions, memory files, configuration, and the workspace reside on the Gateway host (
~/.openclawplus your designated workspace directory). - Remote where unavoidable: messages forwarded to model providers (Anthropic, OpenAI, and others) travel to their API endpoints, and chat platforms (Slack, Telegram, WhatsApp, etc.) retain message data on their own infrastructure.
- You decide the scope: local models keep prompts confined to your hardware, but channel communication always passes through the channel's servers.
See also: Agent workspace, Memory.
Where does OpenClaw store its data?
All data resides under $OPENCLAW_STATE_DIR (default: ~/.openclaw):
| Path | Purpose |
|---|---|
$OPENCLAW_STATE_DIR/openclaw.json | Primary configuration file (JSON5) |
$OPENCLAW_STATE_DIR/credentials/oauth.json | Legacy OAuth import file (copied into auth profiles on first run) |
$OPENCLAW_STATE_DIR/agents/<agentId>/agent/auth-profiles.json | Authentication profiles (OAuth tokens, API keys, optional keyRef/tokenRef) |
$OPENCLAW_STATE_DIR/secrets.json | Optional file-backed secret payload for file SecretRef providers |
$OPENCLAW_STATE_DIR/agents/<agentId>/agent/auth.json | Legacy compatibility file (contains scrubbed static api_key entries) |
$OPENCLAW_STATE_DIR/credentials/ | Provider state (for example whatsapp/<accountId>/creds.json) |
$OPENCLAW_STATE_DIR/agents/ | Per-agent state (agentDir plus legacy and archive session artifacts) |
$OPENCLAW_STATE_DIR/agents/<agentId>/agent/openclaw-agent.sqlite | Per-agent SQLite state, including session rows and transcripts |
$OPENCLAW_STATE_DIR/agents/<agentId>/sessions/ | Legacy session migration sources and archive/support artifacts |
The legacy single-agent path ~/.openclaw/agent/* gets migrated by openclaw doctor.
Your workspace (AGENTS.md, memory files, skills, and so on) is stored separately, configured through agents.defaults.workspace (default: ~/.openclaw/workspace).
Where should AGENTS.md / SOUL.md / USER.md / MEMORY.md live?
These items reside in the agent workspace, not in ~/.openclaw.
- Workspace (per agent):
AGENTS.md,SOUL.md,IDENTITY.md,USER.md,MEMORY.md,memory/YYYY-MM-DD.md, and optionallyHEARTBEAT.md. The lowercase rootmemory.mdis used only for legacy repair input; when both exist,openclaw doctor --fixcan merge it intoMEMORY.md. - State directory (
~/.openclaw): configuration, channel and provider state, authentication profiles, sessions, logs, and shared skills (~/.openclaw/skills).
The default workspace location is ~/.openclaw/workspace, which you can override:
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
}
If the bot appears to "forget" after a restart, verify that the Gateway uses the same workspace on every launch (remote mode employs the gateway host's workspace, not your local machine).
Tip: for persistent behavior or preferences, ask the bot to record them in AGENTS.md or MEMORY.md instead of depending on chat history.
See Agent workspace and Memory.
Can I make SOUL.md bigger?
Yes. SOUL.md is one of the workspace bootstrap files injected into the agent's context. The default per-file injection limit is 20000 characters; the total bootstrap budget across all files is 60000 characters.
Modify shared defaults:
{
agents: {
defaults: {
bootstrapMaxChars: 50000,
bootstrapTotalMaxChars: 300000,
},
},
}
Or override settings for a single agent under agents.entries.*.bootstrapMaxChars / bootstrapTotalMaxChars.
Use /context to inspect raw versus injected sizes and to check whether truncation occurred. Keep SOUL.md focused on tone, stance, and personality; place operational rules in AGENTS.md and persistent facts in memory.
See Context and Agent config.
Recommended backup strategy
Store your agent workspace inside a private git repository and back it up to a secure location, such as a GitHub private repo. This preserves memory along with AGENTS/SOUL/USER files, enabling you to restore the assistant's "mind" later.
Avoid committing anything under ~/.openclaw (credentials, sessions, tokens, encrypted secrets payloads). For a complete restore, back up both the workspace and the state directory separately.
Documentation: Agent workspace.
How do I completely uninstall OpenClaw?
Refer to Uninstall.
Can agents work outside the workspace?
Yes. The workspace serves as the default cwd and memory anchor, not a strict sandbox. Relative paths resolve inside the workspace; absolute paths can reach other host locations unless sandboxing is active. For isolation, use agents.defaults.sandbox or per-agent sandbox configurations. To make a repo the default working directory, point that agent's workspace at the repo root. The OpenClaw repo itself is only source code, so keep the workspace separate unless you intentionally want the agent to operate inside it.
{
agents: {
defaults: {
workspace: "~/Projects/my-repo",
},
},
}
Remote mode: where is the session store?
The gateway host owns session state. In remote mode, the session store you care about resides on the remote machine, not your local laptop. See Session management.
Config basics
What format is the config? Where is it?
OpenClaw reads an optional JSON5 config from $OPENCLAW_CONFIG_PATH (default: ~/.openclaw/openclaw.json). If the file is absent, it applies safe defaults, including a default workspace of ~/.openclaw/workspace.
I set gateway.bind: "lan" (or "tailnet") and now nothing listens / the UI says unauthorized
Non-loopback binds require a valid gateway auth path: shared-secret authentication (token or password), or gateway.auth.mode: "trusted-proxy" behind a properly configured identity-aware reverse proxy.
{
gateway: {
bind: "lan",
auth: {
mode: "token",
token: "replace-me",
},
},
}
gateway.remote.token/.passworddo not independently enable local gateway auth; local call paths can fall back togateway.remote.*only whengateway.auth.*is not set.- For password authentication, set
gateway.auth.mode: "password"together withgateway.auth.password(orOPENCLAW_GATEWAY_PASSWORD). - If
gateway.auth.token/.passwordis explicitly configured via SecretRef and fails to resolve, resolution fails closed (no remote fallback masking). - Shared-secret Control UI setups authenticate using
connect.params.auth.tokenorconnect.params.auth.password(stored in app/UI settings). Identity-bearing modes like Tailscale Serve ortrusted-proxyrely on request headers instead; avoid placing shared secrets in URLs. - With
gateway.auth.mode: "trusted-proxy", same-host loopback reverse proxies require explicitgateway.auth.trustedProxy.allowLoopback = trueand a loopback entry ingateway.trustedProxies.
Why do I need a token on localhost now?
OpenClax enforces gateway auth by default, including loopback. If no explicit auth path is configured, startup defaults to token mode and generates a runtime-only token for that startup, so local WS clients must authenticate. This blocks other local processes from calling the Gateway.
Configure gateway.auth.token, gateway.auth.password, OPENCLAW_GATEWAY_TOKEN, or OPENCLAW_GATEWAY_PASSWORD explicitly when clients need a stable secret across restarts. You can also choose password mode, or trusted-proxy for identity-aware reverse proxies. For open loopback, set gateway.auth.mode: "none" explicitly. openclaw doctor --generate-gateway-token generates a token any time.
Do I have to restart after changing config?
The Gateway monitors the config and supports hot-reload: gateway.reload.mode: "hybrid" (default) hot-applies safe changes and restarts for critical ones. hot, restart, and off are also supported. Most tools.*, agents.* policy, session.*, and messages.* changes apply immediately with no reload action at all; gateway.* binding/port changes require a restart.
How do I enable web search (and web fetch)?
web_fetch functions without an API key. web_search depends on your selected provider.
| Provider | Key-free | Env var(s) |
|---|---|---|
| Brave | No | BRAVE_API_KEY |
| DuckDuckGo | Yes (unofficial HTML-based) | - |
| Exa | No | EXA_API_KEY |
| Firecrawl | No | FIRECRAWL_API_KEY |
| Gemini | No | GEMINI_API_KEY |
| Grok | No (xAI OAuth or key) | XAI_API_KEY |
| Kimi | No | KIMI_API_KEY or MOONSHOT_API_KEY |
| MiniMax Search | No | MINIMAX_CODE_PLAN_KEY, MINIMAX_CODING_API_KEY, or MINIMAX_API_KEY |
| Ollama Web Search | Yes (needs ollama signin) | - |
| Perplexity | No | PERPLEXITY_API_KEY or OPENROUTER_API_KEY |
| SearXNG | Yes (self-hosted) | SEARXNG_BASE_URL |
| Tavily | No | TAVILY_API_KEY |
Grok may also reuse the xAI OAuth token from model authentication via openclaw onboard --auth-choice xai-oauth.
Suggested approach: use openclaw configure --section web and choose a provider.
{
plugins: {
entries: {
brave: {
config: {
webSearch: {
apiKey: "BRAVE_API_KEY_HERE",
},
},
},
},
},
tools: {
web: {
search: {
enabled: true,
provider: "brave",
maxResults: 5,
},
fetch: {
enabled: true,
provider: "firecrawl", // optional; omit for auto-detect
},
},
},
}
Provider-specific web search configuration is placed under plugins.entries.<plugin>.config.webSearch.*. Legacy tools.web.search.* provider paths are still loaded for backward compatibility but should not be used in new configurations. Firecrawl's web-fetch fallback settings are stored under plugins.entries.firecrawl.config.webFetch.*.
- Allowlists: include
web_search/web_fetch/x_search, orgroup:webto cover all three. web_fetchis turned on by default.- When
tools.web.fetch.provideris not provided, OpenClaw automatically selects the first ready fetch fallback provider from the available credentials; the official Firecrawl plugin supplies this fallback. - Daemons read environment variables from
~/.openclaw/.env(or the service environment).
Documentation: Web tools.
config.apply wiped my config. How do I recover and avoid this?
config.apply replaces the entire configuration; a partial object removes everything else.
Current OpenClaw prevents most accidental overwrites:
- Config writes owned by OpenClaw validate the full post-change configuration before applying it.
- Invalid or destructive writes owned by OpenClaw are refused and stored as
openclaw.json.rejected.*. - A direct edit that breaks startup or a hot reload causes the Gateway to fail closed or skip the reload; it does not modify
openclaw.json. openclaw doctor --fixhandles repair, can restore the last known good configuration, and saves the rejected file asopenclaw.json.clobbered.*.
To recover:
- Look in
openclaw logs --followforInvalid config at,Config write rejected:, orconfig reload skipped (invalid config). - Check the most recent
openclaw.json.clobbered.*oropenclaw.json.rejected.*next to the active configuration. - Run
openclaw config validateandopenclaw doctor --fix. - Use
openclaw config setorconfig.patchto copy only the relevant keys back. - If no last known good or rejected payload exists: restore from a backup, or re-run
openclaw doctorand reconfigure channels and models. - If the loss is unexpected: file a bug report with your last known configuration or a backup. A local coding agent can often reconstruct a working configuration from logs or history.
To avoid this: use openclaw config set for small changes, openclaw configure for interactive editing, config.schema.lookup to examine an unfamiliar path (returns a shallow schema node with immediate child summaries), and config.patch for partial RPC edits. Reserve config.apply for full configuration replacement. The agent-facing gateway runtime tool refuses to overwrite tools.exec.ask / tools.exec.security even through legacy tools.bash.* aliases.
Documentation: Config, Configure, Gateway troubleshooting, Doctor.
How do I run a central Gateway with specialized workers across devices?
A recurring setup involves one Gateway (a Raspberry Pi, for instance) plus nodes and agents.
- Gateway (central): manages channels (Signal/WhatsApp), routing, and sessions.
- Nodes (devices): Macs, iOS, and Android machines link up as peripherals, making local tools available (
system.run,canvas,camera). - Agents (workers): separate brains and workspaces dedicated to specific functions (e.g., operations versus personal data).
- Sub-agents: launch background tasks from a main agent to achieve parallelism.
- TUI: connects to the Gateway, allowing you to switch between agents and sessions.
Documentation: Nodes, Remote access, Multi-Agent Routing, Sub-agents, TUI.
Can the OpenClaw browser run headless?
Yes:
{
browser: { headless: true },
agents: {
defaults: {
sandbox: { browser: { headless: true } },
},
},
}
The default is false (headful). Running headless makes anti-bot detection more likely on certain sites (X/Twitter frequently blocks headless sessions). Both modes use the same Chromium engine and work for most automation tasks; the key difference is the absence of a visible browser window (use screenshots to see what is happening). See Browser.
How do I use Brave for browser control?
Set browser.executablePath to point at your Brave binary (or any Chromium-based browser), then restart the Gateway. See Browser.
Remote gateways and nodes
How do commands propagate between Telegram, the gateway, and nodes?
The gateway processes Telegram messages: it runs the agent and only contacts nodes over the Gateway WebSocket when a node tool is required:
Telegram -> Gateway -> Agent -> node.* -> Node -> Gateway -> Telegram
Nodes never see incoming provider traffic; they only handle node RPC calls.
How can my agent access my computer if the Gateway is hosted remotely?
Register your computer as a node. The Gateway runs on a different machine but can invoke node.* tools (screen, camera, system) on your local device via the Gateway WebSocket.
- Run the Gateway on the always-on host (a VPS or home server).
- Place the Gateway host and your computer on the same tailnet.
- Make sure the Gateway WS is reachable (through a tailnet bind or SSH tunnel).
- Open the macOS app locally and connect in Remote over SSH mode (or direct tailnet) so it registers as a node.
- Approve the node:
openclaw devices list openclaw devices approve <requestId>
No separate TCP bridge is needed; nodes connect through the Gateway WebSocket.
Security note: pairing a macOS node gives system.run access to that machine. Only pair devices you trust; review Security.
Documentation: Nodes, Gateway protocol, macOS remote mode, Security.
Tailscale is connected but I get no replies. What now?
Start with the basics:
openclaw gateway status
openclaw status
openclaw channels status
Then check authentication and routing: if you use Tailscale Serve, confirm gateway.auth.allowTailscale is set correctly; if you connect via SSH tunnel, verify the tunnel is active and pointing at the right port; ensure your DM and group allowlists include your account.
Documentation: Tailscale, Remote access, Channels.
Can two OpenClaw instances talk to each other (local + VPS)?
Yes, although no built-in bot-to-bot bridge exists.
Simplest method: use a regular chat channel both bots can access (Slack, Telegram, or WhatsApp). Have Bot A send a message to Bot B, and let Bot B reply as normal.
CLI bridge (generic): run a script that calls the other Gateway with openclaw agent --message ... --deliver, targeting a chat where the other bot listens. If one bot is on a remote VPS, point your CLI at that remote Gateway via SSH or Tailscale (see Remote access):
openclaw agent --message "Hello from local bot" --deliver --channel telegram --reply-to <chat-id>
Add a guardrail to prevent an endless loop between the two bots (mention-only, channel allowlists, or a "do not reply to bot messages" rule).
Documentation: Remote access, Agent CLI, Agent send.
Do I need separate VPSes for multiple agents?
No. A single Gateway can host multiple agents, each with its own workspace, model defaults, and routing. This is the standard configuration and is far cheaper and simpler than running one VPS per agent. Use separate VPS instances only when you need hard isolation (security boundaries) or very different configurations that should not be shared.
Is there a benefit to using a node on my personal laptop instead of SSH from a VPS?
Yes: nodes are the primary way to reach your laptop from a remote Gateway and go beyond simple shell access. The Gateway runs on macOS or Linux (Windows via WSL2) and is lightweight (a small VPS or Raspberry Pi-class machine works; 4 GB RAM is sufficient), so a typical setup is an always-on host plus your laptop acting as a node.
- No inbound SSH required - nodes connect out to the Gateway WebSocket through device pairing.
- Safer execution controls -
system.runis restricted by node allowlists and approvals on that laptop. - More device tools - nodes expose
canvas,camera, andscreenin addition tosystem.run. - Local browser automation - keep the Gateway on a VPS but run Chrome locally through a node host, or attach to local Chrome via Chrome MCP.
SSH works fine for ad-hoc shell access; nodes are simpler for ongoing agent workflows and device automation.
Documentation: Nodes, Nodes CLI, Browser.
Do nodes run a gateway service?
No. Only one gateway should run per host unless you deliberately run isolated profiles (see Multiple gateways). Nodes are peripherals that connect to the gateway (iOS or Android nodes, or macOS "node mode" in the menubar app). For headless node hosts and CLI control, see Node host CLI.
A full restart is required for changes to gateway, discovery, and hosted plugin surfaces.
Is there an API / RPC way to apply config?
Yes:
config.schema.lookup: examine a single configuration subtree along with its shallow schema node, corresponding UI hint, and summaries of its immediate children prior to writing.config.get: retrieve the current snapshot and its hash.config.patch: perform a safe partial update (recommended for most RPC edits); hot-reloads when feasible, restarts when necessary.config.apply: validate and overwrite the entire configuration; hot-reloads when feasible, restarts when necessary.- The agent-facing
gatewayruntime tool still declines to overwritetools.exec.ask/tools.exec.security; legacytools.bash.*aliases are normalized to the same protected paths.
Minimal sane config for a first install
{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
}
Defines your workspace and limits who can activate the bot.
How do I set up Tailscale on a VPS and connect from my Mac?
- Install and log in on the VPS:
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up - Install and log in on your Mac via the Tailscale application, using the same tailnet.
- Activate MagicDNS from the Tailscale admin panel so the VPS gets a fixed name.
- Use the tailnet hostname: SSH
ssh user@your-vps.tailnet-xxxx.ts.net; Gateway WSws://your-vps.tailnet-xxxx.ts.net:18789.
To reach the Control UI without SSH, set up Tailscale Serve on the VPS:
openclaw gateway --tailscale serve
This keeps the gateway bound to loopback and delivers HTTPS through Tailscale. Refer to Tailscale.
How do I connect a Mac node to a remote Gateway (Tailscale Serve)?
Serve exposes the Gateway Control UI and WS; nodes connect using the same Gateway WS endpoint.
- Confirm the VPS and Mac share the same tailnet.
- Run the macOS app in Remote mode (the SSH target can be the tailnet hostname) - it tunnels the Gateway port and joins as a node.
- Approve the node:
openclaw devices list openclaw devices approve <requestId>
Documentation: Gateway protocol, Discovery, macOS remote mode.
Should I install on a second laptop or just add a node?
For local tools only (screen, camera, exec) on the second laptop, register it as a node - one Gateway, no duplicate configuration. Local node tools currently work only on macOS. Install a second Gateway solely for hard isolation or two fully separate bots.
Docs: Nodes, Nodes CLI, Multiple gateways.
Env vars and .env loading
How does OpenClaw load environment variables?
OpenClaw reads environment variables from the parent process (shell, launchd, systemd, CI, etc.) and additionally loads:
.envfrom the current working directory.- a global fallback
.envlocated at~/.openclaw/.env($OPENCLAW_STATE_DIR/.env).
Neither .env file overrides existing environment variables. Provider credentials and endpoint-routing keys are an exception for workspace .env: keys like GEMINI_API_KEY, XAI_API_KEY, MISTRAL_API_KEY, or any key ending in _ENDPOINT (along with other bundled-provider authentication or endpoint env vars) are ignored from workspace .env and should reside in the process environment, ~/.openclaw/.env, or config env.
Inline environment variables in config apply only when absent from the process environment:
{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: { GROQ_API_KEY: "gsk-..." },
},
}
See /environment for the full precedence order and sources.
I started the Gateway via the service and my env vars disappeared. What now?
Two solutions:
- Place the missing keys in
~/.openclaw/.envso they load even when the service does not inherit your shell environment. - Enable shell import (an opt-in convenience):
This runs your login shell and imports only missing expected keys (never overwrites). Environment variable equivalents:{ env: { shellEnv: { enabled: true, timeoutMs: 15000, }, }, }OPENCLAW_LOAD_SHELL_ENV=1,OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000.
I set COPILOT_GITHUB_TOKEN, but models status shows "Shell env: off." Why?
openclaw models status indicates whether shell environment import is active. "Shell env: off" does not mean your environment variables are absent - it simply means OpenClaw will not automatically load your login shell.
If the Gateway runs as a service (launchd or systemd), it will not inherit your shell environment. Fix this by placing the token in ~/.openclaw/.env, enabling env.shellEnv.enabled: true, or adding it to config env (applies only if missing), then restart the gateway and verify:
openclaw models status
Copilot tokens are resolved in this order: OPENCLAW_GITHUB_TOKEN, then COPILOT_GITHUB_TOKEN, then GH_TOKEN, then GITHUB_TOKEN.
Refer to /concepts/model-providers and /environment.
Sessions and multiple chats
How do I start a fresh conversation?
Transmit /new or /reset as an isolated message. Refer to Session management.
Do sessions reset automatically if I never send /new?
Not without explicit configuration. Sessions retain the same sessionId, and compaction limits the active model context as dialogue lengthens. /new and /reset stay accessible, or you can enable automatic resets via mode: "daily" or mode: "idle". Daily mode rotates at session.reset.atHour (4 by default, 0-23) on the gateway machine; idle mode uses session.reset.idleMinutes from the most recent genuine interaction, ignoring heartbeat/cron/exec system events.
{
session: {
reset: { mode: "daily", atHour: 4 },
resetByType: {
group: { mode: "idle", idleMinutes: 120 },
thread: { mode: "daily", atHour: 6 },
},
resetByChannel: {
discord: { mode: "idle", idleMinutes: 10080 },
},
},
}
resetByType accommodates direct, group, and thread. Doctor converts legacy dm records into direct; the schema rejects dm. Older top-level session.idleMinutes continues functioning as a compatibility alias for a default idle mode when no session.reset/resetByType block is defined. Consult Session management for the complete lifecycle.
Is there a way to make a team of OpenClaw instances (one CEO and many agents)?
Yes, through multi-agent routing and sub-agents: a single coordinator agent plus multiple worker agents, each with their own workspace and model.
Consider this a playful experiment. It consumes many tokens and is typically less efficient than using one bot with separate sessions. The usual approach is a single bot you converse with, using different sessions for parallel tasks and spawning sub-agents only when required.
Documentation: Multi-agent routing, Sub-agents, Agents CLI.
Why did context get truncated mid-task? How do I prevent it?
The model window restricts session context. Extended conversations, large tool outputs, or numerous files may trigger compaction or truncation.
- Request the bot to summarise the current state and save it to a file.
- Run
/compactbefore lengthy tasks,/newwhen changing topics. - Preserve essential context in the workspace and ask the bot to re-read it.
- Delegate long or concurrent work to sub-agents so the main chat remains compact.
- Select a model offering a larger context window if this issue arises frequently.
How do I completely reset OpenClaw but keep it installed?
openclaw reset
Complete non-interactive reset:
openclaw reset --scope full --yes --non-interactive
Then re-execute setup:
openclaw onboard --install-daemon
Onboarding provides a Reset option if it identifies an existing configuration; see Onboarding (CLI). If you employed profiles (--profile / OPENCLAW_PROFILE), reset each state directory (default ~/.openclaw-<profile>). Development-only reset: openclaw gateway --dev --reset removes dev configuration, credentials, sessions, and workspace.
I am getting "context too large" errors - how do I reset or compact?
- Compact (preserves the conversation, condenses older turns):
/compactor/compact <instructions>to steer the summary. - Reset (generates a new session ID for the same chat key):
/newor/reset.
If the problem persists, adjust session pruning (agents.defaults.contextPruning) to cut outdated tool output, or switch to a model with a larger context window.
Documentation: Compaction, Session pruning, Session management.
Why am I seeing "LLM request rejected: messages.content.tool_use.input field required"?
Provider validation error: the model produced a tool_use block lacking the mandatory input. This typically indicates stale or corrupted session history, often after lengthy threads or a tool/schema change.
Resolution: begin a new session with /new (standalone message).
Why am I getting heartbeat messages every 30 minutes?
Heartbeats execute every 30 minutes by default, or every 1 hour when the resolved authentication mode is Anthropic OAuth/token auth (including Claude CLI reuse) and heartbeat.every is not set. Adjust or disable:
{
agents: {
defaults: {
heartbeat: {
every: "2h", // or "0m" to disable
},
},
},
}
If HEARTBEAT.md exists but contains only blank lines, Markdown/HTML comments, ATX headings, fence markers, or empty list-item stubs, OpenClaw skips the heartbeat run to conserve API calls. When the file is absent, the heartbeat still runs and the model determines the action.
Per-agent overrides use agents.entries.*.heartbeat. Documentation: Heartbeat.
Do I need to add a "bot account" to a WhatsApp group?
No. OpenClaw operates under your own account. If you belong to the group, OpenClaw can detect it. Group replies are blocked by default until you authorize senders (groupPolicy: "allowlist").
To limit group replies so only you receive them:
{
channels: {
whatsapp: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"],
},
},
}
How do I get the JID of a WhatsApp group?
Quickest approach: follow the logs and send a test message inside the group.
openclaw logs --follow --json
Search for chatId (or from that finishes with @g.us, for instance 1234567890-1234567890@g.us.
If already configured or allowlisted, retrieve groups from the configuration:
openclaw directory groups list --channel whatsapp
Reference materials: WhatsApp, Directory, Logs.
Why does OpenClaw not reply in a group?
Two frequent reasons: mention gating is active by default (you must @mention the bot, or satisfy mentionPatterns), or you set up channels.whatsapp.groups without "*" and the group is not on the allowlist.
Check Groups and Group messages.
Do groups/threads share context with DMs?
Private chats collapse into the main session automatically. Groups and channels each get their own session keys; Telegram topics and Discord threads are treated as separate sessions. See Groups and Group messages.
How many workspaces and agents can I create?
There are no strict limits. Dozens or even hundreds work, but keep an eye on:
- Disk usage: active sessions and transcripts reside in the per-agent SQLite database; older or archived artifacts may still collect under
~/.openclaw/agents/<agentId>/sessions/. - Token consumption: more agents means higher concurrent model usage.
- Administrative effort: each agent requires its own auth profiles, workspaces, and channel routing.
Maintain one active workspace per agent (agents.defaults.workspace), clean up old sessions with openclaw sessions cleanup if disk space becomes an issue (do not manually edit active SQLite data), and use openclaw doctor to detect unused workspaces and mismatched profiles.
Can I run multiple bots or chats at the same time (Slack), and how should I set that up?
Yes, using Multi-Agent Routing: deploy multiple isolated agents and direct incoming messages by channel, account, or peer. Slack is a supported channel and can be assigned to specific agents.
Browser access is powerful but not equivalent to full human capability. Anti-bot systems, CAPTCHAs, and MFA can still block automation. For the most dependable control, use local Chrome MCP on the host, or CDP on the machine that actually runs the browser.
Recommended setup: a permanently running Gateway host (VPS or Mac mini), one agent per role (with bindings), Slack channels tied to those agents, and a local browser through Chrome MCP or a node when required.
Documentation: Multi-Agent Routing, Slack, Browser, Nodes.
Models, failover, and auth profiles
Model Q&A covering defaults, selection, aliases, switching, failover, and auth profiles is available on the Models FAQ.
Gateway: ports, "already running", and remote mode
What port does the Gateway use?
gateway.port manages the single multiplexed port for WebSocket and HTTP (Control UI, hooks, and so on). Priority order:
--port > OPENCLAW_GATEWAY_PORT > gateway.port > default 18789
Why does openclaw gateway status say "Runtime: running" but "Connectivity probe: failed"?
"Running" refers to the supervisor's perspective (launchd, systemd, or schtasks). The connectivity probe is the CLI actually connecting to the gateway WebSocket. Rely on these lines from openclaw gateway status: Probe target: (the URL used by the probe), Listening: (what is actually bound on the port), Last gateway error: (a common root cause when the process is alive but the port is not listening).
Why does openclaw gateway status show "Config (cli)" and "Config (service)" different?
You are editing one configuration file while the service uses a different one (often a --profile or OPENCLAW_STATE_DIR mismatch).
To fix it, execute from the same --profile or environment that the service should use:
openclaw gateway install --force
What does "another gateway instance is already listening" mean?
OpenClaw enforces a runtime lock by binding the WebSocket listener immediately at startup (default ws://127.0.0.1:18789). If binding fails with EADDRINUSE, it returns GatewayLockError ("another gateway instance is already listening").
Resolution: stop the other instance, free the port, or start with openclaw gateway --port <port>.
How do I run OpenClaw in remote mode (client connects to a Gateway elsewhere)?
Set gateway.mode: "remote" and point it to a remote WebSocket URL, optionally including shared-secret remote credentials:
{
gateway: {
mode: "remote",
remote: {
url: "ws://gateway.tailnet:18789",
token: "your-token",
password: "your-password",
},
},
}
openclaw gatewayis initiated only whengateway.modeis set tolocal, unless you supply an override flag.- The macOS application monitors the configuration file and toggles between modes in real time when those values change.
gateway.remote.tokenand.passwordfunction solely as client-side remote credentials; they do not independently enable local gateway authentication.
The Control UI says "unauthorized" (or keeps reconnecting). What now?
The authentication path configured for your gateway does not align with the authentication method used by the UI.
Details from the codebase:
- The Control UI stores the token within
sessionStorage, which is confined to the active browser tab and the chosen gateway URL. This allows refreshes within the same tab to continue functioning without requiring long-term localStorage token persistence. - On
AUTH_TOKEN_MISMATCH, authorized clients may perform a single bounded retry using a cached device token when the gateway provides retry hints (canRetryWithDeviceToken=true,recommendedNextStep=retry_with_device_token). - This cached token retry reuses the approved scopes stored alongside the device token. Callers that explicitly use
deviceTokenorscopesretain their own requested scope set instead of adopting the cached scopes. - Beyond that retry path, the priority order for connect authentication is: explicit shared token or password first, then explicit
deviceToken, followed by a stored device token, and finally a bootstrap token. - The built-in setup code bootstrap returns a node device token containing
scopes: [], along with a bounded operator handoff token intended for trusted mobile onboarding. The operator handoff can access setup time native configuration but lacks permissions for pairing mutation scopes oroperator.admin.
Resolution:
- Quickest approach: run
openclaw dashboard(it prints and copies the dashboard URL, attempts to open it, and shows an SSH hint if running headless). - If no token exists yet: use
openclaw doctor --generate-gateway-token. - For remote access: first establish a tunnel with
ssh -N -L 18789:127.0.0.1:18789 user@host, then openhttp://127.0.0.1:18789/. - In shared secret mode: configure
gateway.auth.tokenandOPENCLAW_GATEWAY_TOKENorgateway.auth.passwordandOPENCLAW_GATEWAY_PASSWORD, then paste the matching secret into the Control UI settings. - For Tailscale Serve mode: verify that
gateway.auth.allowTailscaleis active and that you are opening the Serve URL, not a raw loopback or tailnet URL that would bypass Tailscale identity headers. - In trusted proxy mode: ensure you are connecting through the configured identity aware proxy. Loopback proxies on the same host also require
gateway.auth.trustedProxy.allowLoopback = true. - If the mismatch continues after the single retry: rotate or re approve the paired device token:
openclaw devices list openclaw devices rotate --device <id> --role operator - When rotation is denied: paired device sessions can only rotate their own device unless they also possess
operator.admin, and explicit--scopevalues cannot exceed the caller's current operator scopes. - If still unresolved: run
openclaw status --alland refer to Troubleshooting. Check Dashboard for authentication details.
I set gateway.bind tailnet but it listens only on loopback
Binding with tailnet selects a Tailscale IP from your network interfaces within the 100.64.0.0/10 range. If the machine is not connected to Tailscale, or the Tailscale interface is down, the Gateway falls back to loopback rather than exposing a different network interface.
Solution: start Tailscale on that host and restart the Gateway, or manually switch to gateway.bind: "loopback" or "lan".
tailnet is explicitly configured; auto defaults to loopback. Use gateway.bind: "tailnet" to restrict non loopback exposure to the Tailnet while keeping the necessary same host 127.0.0.1 listener active.
Can I run multiple Gateways on the same host?
Generally no. A single Gateway can handle multiple messaging channels and agents. Deploy multiple Gateways only for redundancy, such as a rescue bot, or for strict isolation. When isolating, give each its own OPENCLAW_CONFIG_PATH, OPENCLAW_STATE_DIR, agents.defaults.workspace, and a unique gateway.port.
Best practice: use openclaw --profile <name> ... per instance (which automatically creates ~/.openclaw-<name>), assign a distinct gateway.port per profile configuration (or --port for manual runs), and set up a per profile service with openclaw --profile <name> gateway install.
Profiles also append suffixes to service names: launchd uses ai.openclaw.<profile>, systemd uses openclaw-gateway-<profile>.service, and Windows uses OpenClaw Gateway (<profile>). The unqualified openclaw-gateway systemd unit exists only for the default profile. The legacy pre rename systemd unit name clawdbot-gateway is migrated automatically.
Complete guide: Multiple gateways.
What does "invalid handshake" / code 1008 mean?
The Gateway operates as a WebSocket server and requires the first message to be a connect frame. Any other type of message causes the connection to close with code 1008, indicating a policy violation.
Common reasons: opening the HTTP URL in a browser rather than using a WS client, using the wrong port or path, or having a proxy or tunnel strip authentication headers or forward a non Gateway request.
Solution: use the WS URL (ws://<host>:18789, or wss://... over HTTPS), avoid opening the WS port in a regular browser tab, and include the token or password in the connect frame when authentication is enabled. CLI or TUI example:
openclaw tui --url ws://<host>:18789 --token <token>
Protocol reference: Gateway protocol.
Logging and debugging
Where are logs?
Structured file logs: use /tmp/openclaw/openclaw-YYYY-MM-DD.log for the default profile, or /tmp/openclaw/openclaw-<profile>-YYYY-MM-DD.log when working with a named profile. Configure a fixed location with logging.file, adjust file logging severity via logging.level, and control console output level through --verbose together with logging.consoleLevel.
Quickest way to follow recent entries:
openclaw logs --follow
Service or supervisor logs (applicable when the gateway runs under launchd or systemd):
- macOS launchd stdout:
~/Library/Logs/openclaw/gateway.log(profiles write togateway-<profile>.log; stderr is not captured). - Linux:
journalctl --user -u openclaw-gateway[-<profile>].service -n 200 --no-pager. - Windows:
schtasks /Query /TN "OpenClaw Gateway (<profile>)" /V /FO LIST.
Additional guidance is in Troubleshooting.
How do I start/stop/restart the Gateway service?
openclaw gateway status
openclaw gateway restart
When operating the gateway manually, openclaw gateway --force can free up the port. Refer to Gateway.
I closed my terminal on Windows - how do I restart OpenClaw?
Three approaches for installing on Windows:
1) Windows Hub local setup: the native application handles a local WSL Gateway that belongs to the app. Launch OpenClaw Companion from either the Start menu or the system tray, then navigate to Gateway Setup or the Connections tab.
2) Manual WSL2 Gateway: the Gateway operates inside a Linux environment.
wsl
openclaw gateway status
openclaw gateway restart
If the service was never installed, launch it in the foreground: openclaw gateway run.
3) Native Windows CLI/Gateway: executes directly within Windows.
openclaw gateway status
openclaw gateway restart
For manual execution without a service: openclaw gateway run.
Documentation: Windows, Gateway service runbook.
The Gateway is up but replies never arrive. What should I check?
Quick health check:
openclaw status
openclaw models status
openclaw channels status
openclaw logs --follow
Frequent reasons: model authentication not loaded on the gateway host (verify with models status), channel pairing or allowlist blocking responses (inspect channel configuration and logs), or WebChat/Dashboard open without the correct token. For remote setups, verify the tunnel or Tailscale connection is active and the Gateway WebSocket can be reached.
Documentation: Channels, Troubleshooting, Remote access.
"Disconnected from gateway: no reason" - what now?
This typically indicates the UI lost its WebSocket link. Verify: is the Gateway running (openclaw gateway status)? Is it reporting healthy (openclaw status)? Does the UI hold the proper token (openclaw dashboard)? For remote scenarios, is the tunnel or Tailscale connection established?
Then follow the logs:
openclaw logs --follow
Documentation: Dashboard, Remote access, Troubleshooting.
Telegram setMyCommands fails. What should I check?
openclaw channels status
openclaw channels logs --channel telegram
Next, identify the error:
BOT_COMMANDS_TOO_MUCH: the Telegram menu contains too many entries. OpenClaw automatically reduces the menu to fit Telegram's limit and retries with fewer commands, though some entries might still be omitted. Cut down on plugin, skill, or custom commands, or turn offchannels.telegram.commands.nativeif the menu is unnecessary.TypeError: fetch failed,Network request for 'setMyCommands' failed!, or comparable network errors: on a VPS or behind a proxy, ensure outbound HTTPS is permitted and DNS resolution works forapi.telegram.org.
When the Gateway is remote, inspect logs on the Gateway host.
Documentation: Telegram, Channel troubleshooting.
TUI shows no output. What should I check?
openclaw status
openclaw models status
openclaw logs --follow
Inside the TUI, run /status to view the current status. If replies are expected in a chat channel, verify that delivery is enabled (/deliver on).
Documentation: TUI, Slash commands.
How do I completely stop then start the Gateway?
If the service was installed (launchd on macOS, systemd on Linux):
openclaw gateway stop
openclaw gateway start
When running in the foreground, stop it with Ctrl-C, then execute openclaw gateway run.
Documentation: Gateway service runbook.
ELI5: openclaw gateway restart vs openclaw gateway
openclaw gateway restart relaunches the background service (launchd/systemd). openclaw gateway starts the gateway in the foreground for the current terminal session. If you have the service installed, rely on the gateway subcommands; otherwise use the standalone foreground command for a single run.
Fastest way to get more details when something fails
Launch the Gateway with --verbose to get more verbose console output, then check the log file for channel authentication, model routing, and RPC errors.
Media and attachments
My skill generated an image/PDF, but nothing was sent
Attachments sent outbound from the agent must use structured media fields like media, mediaUrl, path, or filePath. Refer to OpenClaw assistant setup and Agent send.
openclaw message send --target +15555550123 --message "Here you go" --media /path/to/file.png
Also verify: the destination channel supports outbound media and is not blocked by allowlists; the file stays within the provider's size limits (images are resized to a maximum side of 2048px); tools.fs.workspaceOnly=true restricts local-path sends to workspace, temp/media-store, and sandbox-validated files; tools.fs.workspaceOnly=false (the default) permits structured local media sends to use host-local files the agent already has read access to, for media plus safe document types (images, audio, video, PDF, Office documents, and validated text files such as Markdown/MD, TXT, JSON, YAML/YML). This is not a secret scanner. An agent-readable secret.txt or config.json can be attached when the extension and content validation match. Keep sensitive files outside agent-readable paths, or enable tools.fs.workspaceOnly=true for stricter local-path sends.
See Images.
Security and access control
Is it safe to expose OpenClaw to inbound DMs?
Treat incoming direct messages as untrusted input. Defaults help reduce risk:
- On DM-capable channels, the default behavior is pairing: unknown senders receive a pairing code and their message is not processed. Approve them with
openclaw pairing approve --channel <channel> [--account <id>] <code>. Pending requests are limited to 3 per channel; useopenclaw pairing list --channel <channel> [--account <id>]if a code never arrived. - Opening DMs publicly requires explicit opt-in (
dmPolicy: "open"and allowlist"*").
Run openclaw doctor to surface risky DM policies.
Is prompt injection only a concern for public bots?
No. Prompt injection relates to untrusted content, not just who can DM the bot. If your assistant reads external content (web search/fetch, browser pages, emails, documents, attachments, pasted logs), that content can contain instructions attempting to hijack the model, even if you are the sole sender.
The greatest risk occurs when tools are enabled: the model can be tricked into leaking context or invoking tools on your behalf. Minimize the blast radius:
- Use a read-only or tool-disabled "reader" agent to summarize untrusted content.
- Keep
web_search/web_fetch/browseroff for tool-enabled agents. - Treat decoded file/document text as untrusted too: OpenResponses
input_fileand media-attachment extraction both wrap extracted text in explicit external-content boundary markers instead of passing raw file text. - Sandbox and use strict tool allowlists.
Details: Security.
Is OpenClaw less safe because it uses TypeScript/Node instead of Rust/WASM?
Language and runtime matter, but are not the primary risk for a personal agent. The real risks are gateway exposure, who can message the bot, prompt injection, tool scope, credential handling, browser access, exec access, and third-party skill/plugin trust.
Rust and WASM can offer stronger isolation for certain code classes, but they do not solve prompt injection, bad allowlists, public gateway exposure, overbroad tools, or a browser profile already logged into sensitive accounts. Focus on these primary controls: keep the Gateway private or authenticated, use pairing and allowlists for DMs/groups, deny or sandbox risky tools for untrusted inputs, install only trusted plugins and skills, and run openclaw security audit --deep after config changes.
Details: Security, Sandboxing.
I saw reports about exposed OpenClaw instances. What should I check?
openclaw security audit --deep
openclaw gateway status
A safer baseline: Gateway bound to loopback, or exposed only through authenticated private access (tailnet, SSH tunnel, token/password auth, or a correctly configured trusted proxy); DMs in pairing or allowlist mode; groups allowlisted and mention-gated unless every member is trusted; high-risk tools (exec, browser, gateway, cron) denied or tightly scoped for agents that read untrusted content; sandboxing enabled where tool execution needs a smaller blast radius.
Public binds without auth, open DMs/groups with tools, and exposed browser control are the findings to address first. Details: openclaw security audit.
Are ClawHub skills and third-party plugins safe to install?
Treat third-party skills and plugins as code you are choosing to trust. ClawHub skill pages show scan state before install, but scans are not a complete security boundary. OpenClaw does not run built-in local dangerous-code blocking during plugin/skill install or update; use operator-owned security.installPolicy for local allow/block decisions.
Safer pattern: prefer trusted authors and pinned versions, read the skill/plugin before enabling it, keep plugin/skill allowlists narrow, run untrusted-input workflows in a sandbox with minimal tools, and avoid giving third-party code broad filesystem, exec, browser, or secret access.
Details: Skills, Plugins, Security.
Should my bot have its own email, GitHub account, or phone number?
Yes, for most configurations. Isolating the bot with separate accounts and phone numbers reduces the blast radius if something goes wrong, and makes it easier to rotate credentials or revoke access without affecting your personal accounts.
Start small: give access only to the tools and accounts you actually need, and expand later if required.
Can I give it autonomy over my text messages and is that safe?
We do not recommend full autonomy over your personal messages. Safest pattern: keep DMs in pairing mode or a tight allowlist, use a separate number or account if it should message on your behalf, and let it draft while you approve before sending.
To experiment, do it on a dedicated, isolated account. See Security.
Can I use cheaper models for personal assistant tasks?
Yes, if the agent is chat-only and the input is trusted. Smaller tiers are more susceptible to instruction hijacking, so avoid them for tool-enabled agents or when reading untrusted content. If you must use a smaller model, lock down tools and run inside a sandbox. See Security.
I ran /start in Telegram but did not get a pairing code
Pairing codes are generated exclusively when an unrecognized sender contacts the bot and dmPolicy: "pairing" is active; /start on its own does not produce a code.
View outstanding requests:
openclaw pairing list telegram
For instant access, add your sender ID to the allowlist or configure dmPolicy: "open" for that user.
WhatsApp: will it message my contacts? How does pairing work?
No. The default WhatsApp DM policy is pairing. Unrecognized contacts receive only a pairing code; their message is never processed. OpenClaw responds solely to conversations it has joined or to explicit sends you initiate.
openclaw pairing approve whatsapp <code>
openclaw pairing list whatsapp
The phone number field in the wizard establishes your allowlist/owner so your own direct messages are allowed. It is not used for automated sending. On your personal WhatsApp number, enter that number and activate channels.whatsapp.selfChatMode.
Chat commands, aborting tasks, and "it will not stop"
How do I stop internal system messages from showing in chat?
Most internal and tool messages appear only when verbose, trace, or reasoning is turned on for that session.
Resolve this in the chat where you observe it:
/verbose off
/trace off
/reasoning off
If it remains too chatty: review session settings in the Control UI and set verbose to inherit. Also verify you are not using a bot profile that has verboseDefault: "on" in its configuration.
Reference documentation: Thinking and verbose, Security.
How do I stop/cancel a running task?
Send any of the following as a standalone message (no slash prefix) to stop execution: stop, stop action, stop current action, stop run, stop current run, stop agent, stop the agent, stop openclaw, openclaw stop, stop don't do anything, stop do not do anything, stop doing anything, do not do that, please stop, stop please, abort, esc, exit, interrupt, halt. Common non-English equivalents (French, German, Spanish, Chinese, Japanese, Hindi, Arabic, Russian) are also recognized.
For background tasks launched by the exec tool, instruct the agent to execute:
process action:kill sessionId:XXX
Most slash commands need to be sent as a standalone message beginning with /, though a few shortcuts (such as /status) also function inline for allowlisted senders. See Slash commands.
How do I send a Discord message from Telegram? ("Cross-context messaging denied")
OpenClaw prevents cross-provider messaging by default. If a tool call is associated with Telegram, it will not send to Discord unless you explicitly permit it. This change applies immediately without restarting the gateway:
{
tools: {
message: {
crossContext: {
allowAcrossProviders: true,
marker: { enabled: true, prefix: "[from {channel}] " },
},
},
},
}
Why does it feel like the bot "ignores" rapid-fire messages?
Mid-run prompts are directed into the currently active run by default. Use /queue to select how active runs behave:
steer(default) - route to the active run at the next model boundary.followup- hold messages and process them one after another once the current run finishes.collect- hold compatible messages and respond once after the current run completes.interrupt- cancel the current run and begin a new one.
Add options to queued modes using debounce:0.5s cap:25 drop:summarize. Refer to Command queue and Steering queue.
Miscellaneous
What is the default model for Anthropic with an API key?
Credentials and model selection are handled independently. Configuring ANTHROPIC_API_KEY (or storing an Anthropic API key in auth profiles) enables authentication, but the actual default model is whatever you specify in agents.defaults.model.primary (for instance anthropic/claude-sonnet-4-6 or anthropic/claude-opus-4-6). No credentials found for profile "anthropic:default" indicates the Gateway could not locate Anthropic credentials in the expected auth-profiles.json for the currently running agent.
Still having trouble? Reach out on Discord or start a GitHub discussion.
Related
- For installation, onboarding, authentication, subscriptions, and initial failures, see the First-run FAQ.
- Questions about model selection, failover, and authentication profiles are answered in the Models FAQ.
- The Troubleshooting guide provides symptom based triage.