Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled

Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11),
free to diverge. Tree copied sans upstream .git; upstream remote added for
future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19.
Preserves docs/ARCHITECTURE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
2026-07-05 09:36:54 +00:00
parent 3216769225
commit bedb527145
21108 changed files with 6010766 additions and 0 deletions

257
docs/help/debugging.md Normal file
View File

@@ -0,0 +1,257 @@
---
summary: "Debugging tools: watch mode, raw model streams, and tracing reasoning leakage"
read_when:
- You need to inspect raw model output for reasoning leakage
- You want to run the Gateway in watch mode while iterating
- You need a repeatable debugging workflow
title: "Debugging"
---
Debugging helpers for streaming output, gateway iteration, and startup profiling.
## Runtime debug overrides
`/debug` sets **runtime-only** config overrides (memory, not disk). Disabled by default; enable with `commands.debug: true`.
```text
/debug show
/debug set messages.responsePrefix="[openclaw]"
/debug unset messages.responsePrefix
/debug reset
```
`/debug reset` clears all overrides and returns to the on-disk config.
## Session trace output
`/trace` shows plugin-owned trace/debug lines for one session without enabling full verbose mode. Use it for plugin diagnostics such as Active Memory debug summaries; use `/verbose` for normal status/tool output.
```text
/trace
/trace on
/trace off
```
## Plugin lifecycle trace
Set `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` for a phase-by-phase breakdown of plugin metadata, discovery, registry, runtime mirror, config mutation, and refresh work. Writes to stderr, so JSON command output stays parseable.
```bash
OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1 openclaw plugins install tokenjuice --force
```
```text
[plugins:lifecycle] phase="config read" ms=6.83 status=ok command="install"
[plugins:lifecycle] phase="slot selection" ms=94.31 status=ok command="install" pluginId="tokenjuice"
[plugins:lifecycle] phase="registry refresh" ms=51.56 status=ok command="install" reason="source-changed"
```
Use this before reaching for a CPU profiler. From a source checkout, measure the built runtime with `node dist/entry.js ...` after `pnpm build`; `pnpm openclaw ...` also measures source-runner overhead.
## CLI startup and command profiling
Checked-in startup benchmarks:
```bash
pnpm test:startup:bench:smoke
pnpm tsx scripts/bench-cli-startup.ts --preset real --case status --runs 3
pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu
```
For one-off profiling through the normal source runner, set `OPENCLAW_RUN_NODE_CPU_PROF_DIR`:
```bash
OPENCLAW_RUN_NODE_CPU_PROF_DIR=.artifacts/cli-cpu pnpm openclaw status
```
The source runner adds Node CPU profile flags and writes a `.cpuprofile` for the command. Use this before adding temporary instrumentation to command code.
For startup stalls that look like synchronous filesystem or module-loader work, add Node's sync I/O trace flag through the source runner:
```bash
OPENCLAW_TRACE_SYNC_IO=1 pnpm openclaw gateway --force
```
`pnpm gateway:watch` leaves this flag disabled by default for the watched Gateway child; set `OPENCLAW_TRACE_SYNC_IO=1` when you want sync I/O trace output in watch mode too.
## Gateway watch mode
```bash
pnpm gateway:watch
```
By default this starts or restarts a tmux session named `openclaw-gateway-watch-<profile>` (for example `openclaw-gateway-watch-main`), with a port suffix such as `openclaw-gateway-watch-dev-19001` added only when `OPENCLAW_GATEWAY_PORT` differs from the default port `18789`. It auto-attaches from interactive terminals; non-interactive shells, CI, and agent exec calls stay detached and print attach instructions instead:
```bash
tmux attach -t openclaw-gateway-watch-main
```
The tmux pane runs the raw watcher:
```bash
node scripts/watch-node.mjs gateway --force
```
Foreground mode without tmux:
```bash
pnpm gateway:watch:raw
# or
OPENCLAW_GATEWAY_WATCH_TMUX=0 pnpm gateway:watch
```
Keep tmux management but disable auto-attach:
```bash
OPENCLAW_GATEWAY_WATCH_ATTACH=0 pnpm gateway:watch
```
Profile watched Gateway CPU time when debugging startup/runtime hotspots:
```bash
pnpm gateway:watch --benchmark
```
The watch wrapper consumes `--benchmark` before invoking the Gateway and writes one V8 `.cpuprofile` per Gateway child exit under `.artifacts/gateway-watch-profiles/`. Stop or restart the watched gateway to flush the current profile, then open it with Chrome DevTools or Speedscope:
```bash
npx speedscope .artifacts/gateway-watch-profiles/*.cpuprofile
```
- `--benchmark-dir <path>`: write profiles somewhere else.
- `--benchmark-no-force`: skip the default `--force` port cleanup and fail fast if the Gateway port is already in use.
Benchmark mode suppresses sync-I/O trace spam by default. Set `OPENCLAW_TRACE_SYNC_IO=1` with `--benchmark` to get both CPU profiles and sync-I/O stack traces; in benchmark mode those trace blocks go to `gateway-watch-output.log` under the benchmark directory (filtered from the terminal pane), while normal Gateway logs stay visible.
The tmux wrapper carries common non-secret runtime selectors into the pane, including `OPENCLAW_PROFILE`, `OPENCLAW_CONFIG_PATH`, `OPENCLAW_STATE_DIR`, `OPENCLAW_GATEWAY_PORT`, and `OPENCLAW_SKIP_CHANNELS`. Put provider credentials in your normal profile/config, or use raw foreground mode for one-off ephemeral secrets.
If the watched Gateway exits during startup, the watcher runs `openclaw doctor --fix --non-interactive` once and restarts the Gateway child. Set `OPENCLAW_GATEWAY_WATCH_AUTO_DOCTOR=0` to see the original startup failure without the dev-only repair pass.
The managed tmux pane defaults to colored Gateway logs; set `FORCE_COLOR=0` when starting `pnpm gateway:watch` to disable ANSI output.
The watcher restarts on build-relevant files under `src/`, extension source files, extension `package.json` and `openclaw.plugin.json` metadata, `tsconfig.json`, `package.json`, and `tsdown.config.ts`. Extension metadata changes restart the gateway without forcing a rebuild; source and config changes still rebuild `dist` first.
Add gateway CLI flags after `gateway:watch` and they pass through on each restart. Re-running the same watch command respawns the named tmux pane; the raw watcher keeps a single-watcher lock so duplicate watcher parents are replaced instead of piling up.
## Dev profile + dev gateway (--dev)
Two **separate** `--dev` flags:
- **Global `--dev` (profile):** isolates state under `~/.openclaw-dev` and defaults the gateway port to `19001` (derived ports shift with it).
- **`gateway --dev`:** tells the Gateway to auto-create a default config + workspace when missing (and skip bootstrap).
Recommended flow (dev profile + dev bootstrap):
```bash
pnpm gateway:dev
OPENCLAW_PROFILE=dev openclaw tui
```
Without a global install, run the CLI via `pnpm openclaw ...`.
What this does:
1. **Profile isolation** (global `--dev`)
- `OPENCLAW_PROFILE=dev`
- `OPENCLAW_STATE_DIR=~/.openclaw-dev`
- `OPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.json`
- `OPENCLAW_GATEWAY_PORT=19001` (browser/canvas ports shift accordingly)
2. **Dev bootstrap** (`gateway --dev`)
- Writes a minimal config if missing (`gateway.mode=local`, bind loopback).
- Sets `agents.defaults.workspace` to the dev workspace and `agents.defaults.skipBootstrap=true`.
- Seeds the workspace files if missing: `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`.
- Default identity: **C3-PO** (protocol droid).
- `pnpm gateway:dev` also sets `OPENCLAW_SKIP_CHANNELS=1` to skip channel providers.
Reset flow (fresh start):
```bash
pnpm gateway:dev:reset
```
<Note>
`--dev` is a **global** profile flag and gets eaten by some runners. If you need to spell it out, use the env var form:
```bash
OPENCLAW_PROFILE=dev openclaw gateway --dev --reset
```
</Note>
`--reset` wipes config, credentials, sessions, and the dev workspace (moved to trash, not deleted), then recreates the default dev setup.
<Tip>
If a non-dev gateway is already running (launchd or systemd), stop it first:
```bash
openclaw gateway stop
```
</Tip>
## Raw stream logging
OpenClaw can log the **raw assistant stream** before any filtering/formatting. This is the best way to see whether reasoning is arriving as plain text deltas (or as separate thinking blocks).
Enable it via CLI:
```bash
pnpm gateway:watch --raw-stream
```
Optional path override:
```bash
pnpm gateway:watch --raw-stream --raw-stream-path ~/.openclaw/logs/raw-stream.jsonl
```
Equivalent env vars:
```bash
OPENCLAW_RAW_STREAM=1
OPENCLAW_RAW_STREAM_PATH=~/.openclaw/logs/raw-stream.jsonl
```
Default file: `~/.openclaw/logs/raw-stream.jsonl`
## Safety notes
- Raw stream logs can include full prompts, tool output, and user data.
- Keep logs local and delete them after debugging.
- If you share logs, scrub secrets and PII first.
## Debugging in VSCode
Source maps are required because the build hashes generated filenames. The included `launch.json` targets the Gateway service:
1. **Rebuild and Debug Gateway** - deletes `/dist` and rebuilds with debugging enabled before starting the Gateway.
2. **Debug Gateway** - debugs an existing build without touching `/dist`.
### Setup
1. Open **Run and Debug** (Activity Bar, or `Ctrl`+`Shift`+`D`).
2. Select **Rebuild and Debug Gateway** and press **Start Debugging**.
To manage the build/debug cycle manually instead:
1. Enable source maps in a terminal:
- **Linux/macOS**: `export OUTPUT_SOURCE_MAPS=1`
- **Windows (PowerShell)**: `$env:OUTPUT_SOURCE_MAPS="1"`
- **Windows (CMD)**: `set OUTPUT_SOURCE_MAPS=1`
2. Rebuild: `pnpm clean:dist && pnpm build`
3. Select **Debug Gateway** and press **Start Debugging**.
Set breakpoints in `src/` TypeScript files; the debugger maps them to compiled JavaScript via source maps.
### Notes
- **Rebuild and Debug Gateway** deletes `/dist` and runs a full `pnpm build` with source maps on every launch.
- **Debug Gateway** can start/stop without affecting `/dist`, but you manage the build cycle in a separate terminal.
- Edit `launch.json` `args` to debug other CLI subcommands.
- To use the built CLI for other tasks (for example `dashboard --no-open` if your debug session spawns a new auth token), run it from another terminal: `node ./openclaw.mjs` or an alias like `alias openclaw-build="node $(pwd)/openclaw.mjs"`.
## Related
- [Troubleshooting](/help/troubleshooting)
- [FAQ](/help/faq)

239
docs/help/environment.md Normal file
View File

@@ -0,0 +1,239 @@
---
summary: "Where OpenClaw loads environment variables and the precedence order"
read_when:
- You need to know which env vars are loaded, and in what order
- You are debugging missing API keys in the Gateway
- You are documenting provider auth or deployment environments
title: "Environment variables"
---
OpenClaw pulls environment variables from multiple sources. The rule is **never override existing values**.
Workspace `.env` files are a lower-trust source: OpenClaw ignores provider credentials and protected runtime controls from workspace `.env` before applying precedence.
## Precedence (highest to lowest)
1. **Process environment** (what the Gateway process already has from the parent shell/daemon).
2. **`.env` in the current working directory** (dotenv default; does not override; provider credentials and protected runtime controls are ignored).
3. **Global `.env`** at `~/.openclaw/.env` (aka `$OPENCLAW_STATE_DIR/.env`; recommended for provider API keys; does not override).
4. **Config `env` block** in `~/.openclaw/openclaw.json` (applied only if missing).
5. **Optional login-shell import** (`env.shellEnv.enabled` or `OPENCLAW_LOAD_SHELL_ENV=1`), applied only for missing expected keys.
On fresh Ubuntu installs that use the default state dir, OpenClaw also treats `~/.config/openclaw/gateway.env` as a compatibility fallback after the global `.env`. If both files exist and disagree, OpenClaw keeps `~/.openclaw/.env` and prints a warning.
If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.
## Provider credentials and workspace `.env`
Do not keep provider API keys only in a workspace `.env`. OpenClaw blocks a large set of provider credential and endpoint-redirect keys from workspace `.env` files, including every known provider auth env var (for example `GEMINI_API_KEY`, `GOOGLE_API_KEY`, `XAI_API_KEY`, `MISTRAL_API_KEY`, `GROQ_API_KEY`, `DEEPSEEK_API_KEY`, `PERPLEXITY_API_KEY`, `BRAVE_API_KEY`, `TAVILY_API_KEY`, `EXA_API_KEY`, `FIRECRAWL_API_KEY`), plus any key ending in `_API_HOST`, `_BASE_URL`, or `_HOMESERVER`, and the entire `OPENCLAW_*`, `CLAWHUB_*`, `ANTHROPIC_API_KEY_*`, and `OPENAI_API_KEY_*` namespaces.
Use one of these trusted sources for provider credentials instead:
- The Gateway process environment, such as a shell, launchd/systemd unit, container secret, or CI secret.
- The global runtime dotenv file at `~/.openclaw/.env` or `$OPENCLAW_STATE_DIR/.env`.
- The config `env` block in `~/.openclaw/openclaw.json`.
- Optional login-shell import when `env.shellEnv.enabled` or `OPENCLAW_LOAD_SHELL_ENV=1` is enabled.
If you previously stored provider keys only in a workspace `.env`, move them to one of the trusted sources above. Workspace `.env` can still provide ordinary project variables that are not credentials, endpoint redirects, host overrides, or `OPENCLAW_*` runtime controls.
See [Workspace `.env` files](/gateway/security#workspace-env-files) for the security rationale.
## Config `env` block
Two equivalent ways to set inline env vars (both are non-overriding):
```json5
{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: {
GROQ_API_KEY: "gsk-...",
},
},
}
```
The config `env` block accepts literal string values only. It does not expand
`file:...` values; for example, `XAI_API_KEY: "file:secrets/xai-api-key.txt"`
is passed to providers as that exact string.
For file-backed provider keys, use a SecretRef on the credential field that
supports it:
```json5
{
secrets: {
providers: {
xai_key_file: {
source: "file",
path: "~/.openclaw/secrets/xai-api-key.txt",
mode: "singleValue",
},
},
},
models: {
providers: {
xai: {
apiKey: { source: "file", provider: "xai_key_file", id: "value" },
},
},
},
}
```
See [Secrets Management](/gateway/secrets) and the
[SecretRef credential surface](/reference/secretref-credential-surface) for
supported fields.
## Shell env import
`env.shellEnv` runs your login shell and imports only **missing** expected keys:
```json5
{
env: {
shellEnv: {
enabled: true,
timeoutMs: 15000,
},
},
}
```
Env var equivalents:
- `OPENCLAW_LOAD_SHELL_ENV=1`
- `OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000` (default `15000`)
## Exec shell snapshots
On non-Windows Gateway hosts, bash and zsh `exec` commands use a startup snapshot by default.
Set `OPENCLAW_EXEC_SHELL_SNAPSHOT=0` in the Gateway process environment to disable this path.
Values `false`, `no`, and `off` also disable it. Per-call `exec.env` values cannot toggle
snapshots or redirect the snapshot cache.
## Runtime-injected env vars
OpenClaw also injects context markers into spawned child processes:
- `OPENCLAW_SHELL=exec`: set for commands run through the `exec` tool.
- `OPENCLAW_SHELL=acp-client`: set for `openclaw acp client` when it spawns the ACP bridge process.
- `OPENCLAW_SHELL=tui-local`: set for local TUI `!` shell commands.
- `OPENCLAW_CLI=1`: set for child processes spawned by the CLI entry point.
These are runtime markers (not required user config). They can be used in shell/profile logic
to apply context-specific rules.
## UI env vars
- `OPENCLAW_THEME=light`: force the light TUI palette when your terminal has a light background.
- `OPENCLAW_THEME=dark`: force the dark TUI palette.
- `COLORFGBG`: if your terminal exports it, OpenClaw uses the background color hint to auto-pick the TUI palette.
## Env var substitution in config
You can reference env vars directly in config string values using `${VAR_NAME}` syntax:
```json5
{
models: {
providers: {
"vercel-gateway": {
apiKey: "${VERCEL_GATEWAY_API_KEY}",
},
},
},
}
```
See [Configuration: Env var substitution](/gateway/configuration-reference#env-var-substitution) for full details.
## Secret refs vs `${ENV}` strings
OpenClaw supports two env-driven patterns:
- `${VAR}` string substitution in config values.
- SecretRef objects (`{ source: "env", provider: "default", id: "VAR" }`) for fields that support secrets references.
Both resolve from process env at activation time. SecretRef details are documented in [Secrets Management](/gateway/secrets).
The config `env` block itself does not resolve SecretRefs or `file:...`
shorthand values.
## Path-related env vars
| Variable | Purpose |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OPENCLAW_HOME` | Override the home directory used for internal OpenClaw path defaults (`~/.openclaw/`, agent dirs, sessions, credentials, installer onboarding, and the default dev checkout). Useful when running OpenClaw as a dedicated service user. |
| `OPENCLAW_STATE_DIR` | Override the state directory (default `~/.openclaw`). |
| `OPENCLAW_CONFIG_PATH` | Override the config file path (default `~/.openclaw/openclaw.json`). |
| `OPENCLAW_INCLUDE_ROOTS` | Path-list of directories where `$include` directives may resolve files outside the config directory (default: none - `$include` is confined to the config dir). Tilde-expanded. |
## Logging
| Variable | Purpose |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OPENCLAW_LOG_LEVEL` | Override log level for both file and console (e.g. `debug`, `trace`). Takes precedence over `logging.level` and `logging.consoleLevel` in config. Invalid values are ignored with a warning. |
| `OPENCLAW_DEBUG_MODEL_TRANSPORT` | Emit targeted model request/response timing diagnostics at `info` level without enabling global debug logs. |
| `OPENCLAW_DEBUG_MODEL_PAYLOAD` | Model payload diagnostics: `summary`, `tools`, or `full-redacted`. `full-redacted` is capped and redacted but may include prompt/message text. |
| `OPENCLAW_DEBUG_SSE` | Streaming diagnostics: `events` for first/done timing, `peek` to include the first five redacted SSE events. |
| `OPENCLAW_DEBUG_CODE_MODE` | Code-mode model-surface diagnostics, including provider-tool hiding and exec/wait-only enforcement. |
### `OPENCLAW_HOME`
When set, `OPENCLAW_HOME` replaces the system home directory (`$HOME` / `os.homedir()`) for internal OpenClaw path defaults. This includes the default state directory, config path, agent directories, credentials, installer onboarding workspace, and the default dev checkout used by `openclaw update --channel dev`.
**Precedence:** `OPENCLAW_HOME` > `$HOME` > `USERPROFILE` > Termux `PREFIX` home fallback on Android > `os.homedir()`
**Example** (macOS LaunchDaemon):
```xml
<key>EnvironmentVariables</key>
<dict>
<key>OPENCLAW_HOME</key>
<string>/Users/user</string>
</dict>
```
`OPENCLAW_HOME` can also be set to a tilde path (e.g. `~/svc`), which gets expanded using the same OS home fallback chain before use.
Explicit path variables such as `OPENCLAW_STATE_DIR`, `OPENCLAW_CONFIG_PATH`, and `OPENCLAW_GIT_DIR` still take precedence. OS-account tasks such as shell startup file detection, package-manager setup, and host `~` expansion may still use the real system home.
## nvm users: web_fetch TLS failures
If Node.js was installed via **nvm** (not the system package manager), the built-in `fetch()` uses
nvm's bundled CA store, which may be missing modern root CAs (ISRG Root X1/X2 for Let's Encrypt,
DigiCert Global Root G2, etc.). This causes `web_fetch` to fail with `"fetch failed"` on most HTTPS sites.
On Linux, OpenClaw automatically detects nvm and applies the fix in the actual startup environment:
- `openclaw gateway install` writes `NODE_EXTRA_CA_CERTS` into the systemd service environment
- the `openclaw` CLI entrypoint re-execs itself with `NODE_EXTRA_CA_CERTS` set before Node startup
**Manual fix (for older versions or direct `node ...` launches):**
Export the variable before starting OpenClaw:
```bash
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
openclaw gateway run
```
Do not rely on writing only to `~/.openclaw/.env` for this variable; Node reads
`NODE_EXTRA_CA_CERTS` at process startup.
## Legacy environment variables
OpenClaw only reads `OPENCLAW_*` environment variables. The legacy
`CLAWDBOT_*` and `MOLTBOT_*` prefixes from earlier releases are silently
ignored.
If any are still set on the Gateway process at startup, OpenClaw emits a
single Node deprecation warning (`OPENCLAW_LEGACY_ENV_VARS`) listing the
detected prefixes and the total count. Rename each value by replacing the
legacy prefix with `OPENCLAW_` (for example `CLAWDBOT_GATEWAY_TOKEN` to
`OPENCLAW_GATEWAY_TOKEN`); the old names take no effect.
## Related
- [Gateway configuration](/gateway/configuration)
- [FAQ: env vars and .env loading](/help/faq#env-vars-and-env-loading)
- [Models overview](/concepts/models)

824
docs/help/faq-first-run.md Normal file
View File

@@ -0,0 +1,824 @@
---
summary: "FAQ: quick-start and first-run setup — install, onboard, auth, subscriptions, initial failures"
read_when:
- New install, onboarding stuck, or first-run errors
- Choosing auth and provider subscriptions
- Cannot access docs.openclaw.ai, cannot open dashboard, install stuck
title: "FAQ: first-run setup"
sidebarTitle: "First-run FAQ"
---
Quick-start and first-run Q&A. For everyday operations, models, auth, sessions,
and troubleshooting see the main [FAQ](/help/faq).
## Quick start and first-run setup
<AccordionGroup>
<Accordion title="I am stuck, fastest way to get unstuck">
Use a local AI agent that can **see your machine**. Most "I'm stuck" cases are
**local config or environment issues** a remote helper cannot inspect, so this beats
asking in Discord.
- **Claude Code**: [https://www.anthropic.com/claude-code/](https://www.anthropic.com/claude-code/)
- **OpenAI Codex**: [https://openai.com/codex/](https://openai.com/codex/)
Give the agent the full source checkout via the hackable (git) install so it can read
code + docs and reason about the exact version you run:
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
```
Ask the agent to plan and supervise the fix step-by-step, then execute only the
necessary commands - smaller diffs are easier to audit.
Share these outputs when asking for help (in Discord or a GitHub issue):
| Command | Shows |
| --- | --- |
| `openclaw status` | Gateway/agent health + basic config snapshot |
| `openclaw status --all` | Full read-only diagnosis, pasteable |
| `openclaw models status` | Provider auth + model availability |
| `openclaw doctor` | Validates and repairs common config/state issues |
| `openclaw logs --follow` | Live log tail |
| `openclaw gateway status --deep` | Deep gateway/config/plugin health check |
| `openclaw health --verbose` | Detailed health report |
Found a real bug or fix? File an issue or send a PR:
[Issues](https://github.com/openclaw/openclaw/issues) /
[Pull requests](https://github.com/openclaw/openclaw/pulls).
Quick debug loop: [First 60 seconds if something is broken](/help/faq#first-60-seconds-if-something-is-broken).
Install docs: [Install](/install), [Installer flags](/install/installer), [Updating](/install/updating).
</Accordion>
<Accordion title="Heartbeat keeps skipping. What do the skip reasons mean?">
| Skip reason | Meaning |
| --- | --- |
| `quiet-hours` | Outside the configured active-hours window |
| `empty-heartbeat-file` | `HEARTBEAT.md` exists but only has blank, comment, header, fence, or empty-checklist scaffolding |
| `no-tasks-due` | Task mode is active but no task interval is due yet |
| `alerts-disabled` | All heartbeat visibility is off (`showOk`, `showAlerts`, and `useIndicator` all disabled) |
In task mode, due timestamps advance only after a real heartbeat run completes.
Skipped runs do not mark tasks as completed.
Docs: [Heartbeat](/gateway/heartbeat), [Automation](/automation).
</Accordion>
<Accordion title="Recommended way to install and set up OpenClaw">
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
openclaw onboard --install-daemon
```
From source (contributors/dev):
```bash
git clone https://github.com/openclaw/openclaw.git
cd openclaw
pnpm install
pnpm build
pnpm ui:build
openclaw onboard
```
No global install yet? Run `pnpm openclaw onboard` instead. If Control UI assets are
missing, onboarding tries to build them itself, falling back to `pnpm ui:build`.
</Accordion>
<Accordion title="How do I open the dashboard after onboarding?">
Onboarding opens your browser to a clean (non-tokenized) dashboard URL right after
setup and prints the link in the summary. Keep that tab open; if it did not launch,
copy/paste the printed URL on the same machine.
</Accordion>
<Accordion title="How do I authenticate the dashboard on localhost vs remote?">
**Localhost (same machine):**
- Open `http://127.0.0.1:18789/`.
- If it asks for shared-secret auth, paste the configured token or password into Control UI settings.
- Token source: `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`).
- Password source: `gateway.auth.password` (or `OPENCLAW_GATEWAY_PASSWORD`).
- No shared secret configured yet? Run `openclaw doctor --generate-gateway-token` (or `openclaw doctor --fix --generate-gateway-token`).
**Not on localhost:**
- **Tailscale Serve** (recommended): keep bind loopback, run `openclaw gateway --tailscale serve`, open `https://<magicdns>/`. With `gateway.auth.allowTailscale: true`, identity headers satisfy Control UI/WebSocket auth (no pasted shared secret, assumes a trusted gateway host); HTTP APIs still need shared-secret auth unless you deliberately use private-ingress `none` or trusted-proxy HTTP auth.
Concurrent bad-auth Serve attempts from the same client are serialized before the failed-auth limiter records them, so a second bad retry can already show `retry later`.
- **Tailnet bind**: run `openclaw gateway --bind tailnet --token "<token>"` (or configure password auth), open `http://<tailscale-ip>:18789/`, paste the matching shared secret in dashboard settings.
- **Identity-aware reverse proxy**: keep the Gateway behind a trusted proxy, set `gateway.auth.mode: "trusted-proxy"`, open the proxy URL. Same-host loopback proxies need explicit `gateway.auth.trustedProxy.allowLoopback: true`.
- **SSH tunnel**: `ssh -N -L 18789:127.0.0.1:18789 user@gateway-host`, then open `http://127.0.0.1:18789/`. Shared-secret auth still applies over the tunnel; paste the configured token or password if prompted.
See [Dashboard](/web/dashboard) and [Web surfaces](/web) for bind modes and auth details.
</Accordion>
<Accordion title="Why are there two exec approval configs for chat approvals?">
They control different layers:
- `approvals.exec` - forwards approval prompts to chat destinations.
- `channels.<channel>.execApprovals` - makes that channel a native approval client for exec approvals.
The host exec policy is still the real approval gate; chat config only controls where
prompts appear and how people answer them.
You rarely need both:
- If the chat already supports commands and replies, same-chat `/approve` works through the shared path.
- When a supported native channel can infer approvers safely, OpenClaw auto-enables DM-first native approvals if `channels.<channel>.execApprovals.enabled` is unset or `"auto"`.
- When native approval cards/buttons are available, that UI is primary; only mention a manual `/approve` command if the tool result says chat approvals are unavailable.
- Use `approvals.exec` only when prompts must also reach other chats or explicit ops rooms.
- Use `channels.<channel>.execApprovals.target: "channel"` or `"both"` only when you want approval prompts posted back into the originating room/topic.
- Plugin approvals are separate: same-chat `/approve` by default, optional `approvals.plugin` forwarding, and only some native channels keep native handling for those too.
Short version: forwarding is for routing, native client config is for richer channel-specific UX.
See [Exec Approvals](/tools/exec-approvals).
</Accordion>
<Accordion title="What runtime do I need?">
Node **22.19+** is required (Node 24 recommended). `pnpm` is the repo package manager.
Bun is **not recommended** for the Gateway.
</Accordion>
<Accordion title="Does it run on Raspberry Pi?">
Yes, but check RAM first: Pi 5 and Pi 4 (2 GB+) are the sweet spot; Pi 3B+ (1 GB) works but is slow; Pi Zero 2 W (512 MB) is not recommended.
| Model | RAM | Fit |
| --- | --- | --- |
| Pi 5 | 4/8 GB | Best |
| Pi 4 | 4 GB | Good |
| Pi 4 | 2 GB | OK, add swap |
| Pi 4 | 1 GB | Tight |
| Pi 3B+ | 1 GB | Slow |
| Pi Zero 2 W | 512 MB | Not recommended |
Absolute minimum: 1 GB RAM, 1 core, 500 MB free disk, 64-bit OS. Since the Pi only runs
the Gateway (models call out to cloud APIs), even a modest Pi handles the load.
A small Pi/VPS can also host just the Gateway while you pair **nodes** on your
laptop/phone for local screen/camera/canvas or command execution. See [Nodes](/nodes).
Full setup walkthrough: [Raspberry Pi](/install/raspberry-pi).
</Accordion>
<Accordion title="Any tips for Raspberry Pi installs?">
- Use a **64-bit** OS; do not use 32-bit Raspberry Pi OS.
- Add swap on 2 GB or smaller boards.
- Prefer a **USB SSD** over an SD card for performance and longevity.
- Prefer the hackable (git) install so you can see logs and update fast.
- Start without channels/skills, add them one by one.
- Weird binary failures ("exec format error") are usually a missing ARM64 build for an optional skill tool.
Full guide: [Raspberry Pi](/install/raspberry-pi). Also see [Linux](/platforms/linux).
</Accordion>
<Accordion title="It is stuck on wake up my friend / onboarding will not hatch. What now?">
That screen depends on the Gateway being reachable and authenticated. The TUI also sends
"Wake up, my friend!" automatically on first hatch. If you see that line with **no reply**
and tokens stay at 0, the agent never ran.
1. Restart the Gateway:
```bash
openclaw gateway restart
```
2. Check status + auth:
```bash
openclaw status
openclaw models status
openclaw logs --follow
```
3. Still hanging? Run:
```bash
openclaw doctor
```
If the Gateway is remote, confirm the tunnel/Tailscale connection is up and the UI
points at the right Gateway. See [Remote access](/gateway/remote).
</Accordion>
<Accordion title="Can I migrate my setup to a new machine without redoing onboarding?">
Yes. Copy the **state directory** and **workspace**, then run Doctor once:
1. Install OpenClaw on the new machine.
2. Copy `$OPENCLAW_STATE_DIR` (default: `~/.openclaw`) from the old machine.
3. Copy your workspace (default: `~/.openclaw/workspace`).
4. Run `openclaw doctor` and restart the Gateway service.
This preserves config, auth profiles, WhatsApp creds, sessions, and memory - it keeps
your bot exactly the same, as long as you copy **both** locations. In remote mode, the
gateway host owns the session store and workspace.
**Important:** if you only commit/push your workspace to GitHub, you back up
**memory + bootstrap files**, but not session history or auth. Those live under
`~/.openclaw/` (for example `~/.openclaw/agents/<agentId>/sessions/`).
Related: [Migrating](/install/migrating), [Where things live on disk](/help/faq#where-things-live-on-disk),
[Agent workspace](/concepts/agent-workspace), [Doctor](/gateway/doctor),
[Remote mode](/gateway/remote).
</Accordion>
<Accordion title="Where do I see what is new in the latest version?">
Check the GitHub changelog:
[https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md)
Newest entries are at the top. If the top section is **Unreleased**, the next dated
section is the latest shipped version. Entries group under **Highlights**, **Changes**,
and **Fixes** (plus docs/other sections when needed).
</Accordion>
<Accordion title="Cannot access docs.openclaw.ai (SSL error)">
Some Comcast/Xfinity connections incorrectly block `docs.openclaw.ai` via Xfinity
Advanced Security. Disable it or allowlist `docs.openclaw.ai`, then retry. Help us
get it unblocked: [https://spa.xfinity.com/check_url_status](https://spa.xfinity.com/check_url_status).
Still blocked? Docs are mirrored on GitHub:
[https://github.com/openclaw/openclaw/tree/main/docs](https://github.com/openclaw/openclaw/tree/main/docs)
</Accordion>
<Accordion title="Difference between stable and beta">
**Stable** and **beta** are **npm dist-tags**, not separate code lines:
- `latest` = stable
- `beta` = early build for testing (falls back to `latest` when beta is missing or older than the current stable release)
A stable release usually lands on **beta** first, then an explicit promotion step
moves that same version to `latest` without changing the version number. Maintainers
can also publish straight to `latest`. That is why beta and stable can point at the
**same version** after promotion.
See what changed: [CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md).
For install one-liners and the difference between beta and dev, see the next accordion.
</Accordion>
<Accordion title="How do I install the beta version and what is the difference between beta and dev?">
**Beta** is the npm dist-tag `beta` (may match `latest` after promotion).
**Dev** is the moving head of `main` (git); when published to npm it uses dist-tag `dev`.
One-liners (macOS/Linux):
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --beta
```
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
```
Windows installer (PowerShell): `iwr -useb https://openclaw.ai/install.ps1 | iex`
More detail: [Development channels](/install/development-channels) and [Installer flags](/install/installer).
</Accordion>
<Accordion title="How do I try the latest bits?">
Two options:
1. **Dev channel (existing install):**
```bash
openclaw update --channel dev
```
This switches to a git checkout of `main`, rebases on upstream, builds, and installs
the CLI from that checkout.
2. **Hackable (git) install (fresh machine):**
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
```
Prefer a manual clone:
```bash
git clone https://github.com/openclaw/openclaw.git
cd openclaw
pnpm install
pnpm build
```
Docs: [Update](/cli/update), [Development channels](/install/development-channels), [Install](/install).
</Accordion>
<Accordion title="How long does install and onboarding usually take?">
Rough guide:
- **Install:** 2-5 minutes.
- **QuickStart onboarding:** a few minutes (loopback gateway, auto token, default workspace).
- **Advanced/full onboarding:** longer when provider sign-in, channel pairing, daemon install, network downloads, or skills need extra setup.
The wizard shows this timeline up front. Skip optional steps and return later with
`openclaw configure`.
Hanging? See [I am stuck](#quick-start-and-first-run-setup) above.
</Accordion>
<Accordion title="Installer stuck? How do I get more feedback?">
Re-run with `--verbose`:
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --verbose
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --beta --verbose
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git --verbose
```
`install.ps1` has no dedicated verbose switch; wrap it in `Set-PSDebug -Trace 1` /
`-Trace 0` instead. Full flag reference: [Installer flags](/install/installer).
</Accordion>
<Accordion title="Windows install says git not found or openclaw not recognized">
Two common Windows issues:
**1) npm error spawn git / git not found**
- Install **Git for Windows**, make sure `git` is on PATH.
- Close and reopen PowerShell, then re-run the installer.
**2) openclaw is not recognized after install**
- Your npm global bin folder is not on PATH.
- Check it: `npm config get prefix`.
- Add that directory to your user PATH (no `\bin` suffix needed; on most systems it is `%AppData%\npm`).
- Close and reopen PowerShell.
Prefer a desktop app? Use **Windows Hub**. Terminal-only setup: the PowerShell
installer and WSL2 Gateway paths are both supported. Docs: [Windows](/platforms/windows).
</Accordion>
<Accordion title="Windows exec output shows garbled Chinese text - what should I do?">
Usually a console code page mismatch on native Windows shells.
Symptoms: `system.run`/`exec` output renders Chinese as mojibake; the same command
looks fine in another terminal profile.
Workaround in PowerShell:
```powershell
chcp 65001
[Console]::InputEncoding = [System.Text.UTF8Encoding]::new($false)
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
```
Then restart the Gateway and retry:
```powershell
openclaw gateway restart
```
Still reproducing this on latest OpenClaw? Track/report it: [Issue #30640](https://github.com/openclaw/openclaw/issues/30640).
</Accordion>
<Accordion title="The docs did not answer my question - how do I get a better answer?">
Use the hackable (git) install so you have the full source and docs locally, then ask
your bot (or Claude/Codex) **from that folder** so it can read the repo and answer precisely.
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
```
More detail: [Install](/install) and [Installer flags](/install/installer).
</Accordion>
<Accordion title="How do I install OpenClaw on Linux?">
- Linux quick path + service install: [Linux](/platforms/linux).
- Full walkthrough: [Getting Started](/start/getting-started).
- Installer + updates: [Install & updates](/install/updating).
</Accordion>
<Accordion title="How do I install OpenClaw on a VPS?">
Any Linux VPS works. Install on the server, then reach the Gateway over SSH/Tailscale.
Guides: [exe.dev](/install/exe-dev), [Hetzner](/install/hetzner), [Fly.io](/install/fly).
Remote access: [Gateway remote](/gateway/remote).
</Accordion>
<Accordion title="Where are the cloud/VPS install guides?">
Hosting hub with common providers:
- [VPS hosting](/vps) (all providers in one place)
- [Fly.io](/install/fly)
- [Hetzner](/install/hetzner)
- [exe.dev](/install/exe-dev)
In the cloud, the **Gateway runs on the server** and you access it from your laptop/phone
via the Control UI (or Tailscale/SSH). Your state + workspace live on the server, so
treat the host as the source of truth and back it up.
Pair **nodes** (Mac/iOS/Android/headless) to that cloud Gateway for local
screen/camera/canvas or command execution on your laptop while the Gateway stays in
the cloud.
Hub: [Platforms](/platforms). Remote access: [Gateway remote](/gateway/remote).
Nodes: [Nodes](/nodes), [Nodes CLI](/cli/nodes).
</Accordion>
<Accordion title="Can I ask OpenClaw to update itself?">
Possible, not recommended. The update flow can restart the Gateway (dropping the
active session), may need a clean git checkout, and can prompt for confirmation.
Safer to run updates from a shell as the operator.
```bash
openclaw update
openclaw update status
openclaw update --channel stable|extended-stable|beta|dev
openclaw update --tag <dist-tag|version>
openclaw update --no-restart
```
Automating from an agent:
```bash
openclaw update --yes --no-restart
openclaw gateway restart
```
Docs: [Update](/cli/update), [Updating](/install/updating).
</Accordion>
<Accordion title="What does onboarding actually do?">
`openclaw onboard` is the recommended setup path. In **local mode** it walks through:
1. **Model/Auth** - provider OAuth, API keys, or manual auth (including local options like LM Studio); pick a default model.
2. **Workspace** - location + bootstrap files.
3. **Gateway** - port, bind address, auth mode, Tailscale exposure.
4. **Channels** - built-in and official plugin chat channels: iMessage, Discord, Feishu, Google Chat, Mattermost, Microsoft Teams, QQ Bot, Signal, Slack, Telegram, WhatsApp, and more.
5. **Daemon** - LaunchAgent (macOS), systemd user unit (Linux/WSL2), or native Windows Scheduled Task.
6. **Health check** - starts the Gateway and verifies it is running.
7. **Skills** - installs recommended skills and optional dependencies.
It sets duration expectations up front and warns if your configured model is unknown
or missing auth. Full breakdown: [Onboarding (CLI)](/start/wizard).
</Accordion>
<Accordion title="Do I need a Claude or OpenAI subscription to run this?">
No. Run OpenClaw with **API keys** (Anthropic/OpenAI/others) or **local-only models**
so your data stays on your device. Subscriptions (Claude Pro/Max, ChatGPT/Codex) are
optional ways to authenticate those providers.
For Anthropic: an **API key** gives standard pay-as-you-go billing; **Claude CLI**
reuses an existing Claude Code login on the same host. Anthropic currently treats
Claude CLI's non-interactive `claude -p` path as Agent SDK/programmatic usage that
still draws from your subscription's plan limits - check current Anthropic billing
docs before relying on subscription behavior. For long-lived gateway hosts and shared
automation, an Anthropic API key is the more predictable choice.
OpenAI Codex OAuth (ChatGPT/Codex subscription) is fully supported for agent models.
OpenClaw also supports hosted subscription-style options including **Qwen Cloud
Coding Plan**, **MiniMax Coding Plan**, and **Z.AI / GLM Coding Plan**.
Docs: [Anthropic](/providers/anthropic), [OpenAI](/providers/openai),
[Qwen Cloud](/providers/qwen), [MiniMax](/providers/minimax), [Z.AI (GLM)](/providers/zai),
[Local models](/gateway/local-models), [Models](/concepts/models).
</Accordion>
<Accordion title="Can I use Claude Max subscription without an API key?">
Yes. OpenClaw supports Claude CLI reuse for Pro/Max/Team/Enterprise plans. Anthropic
currently treats the `claude -p` path OpenClaw uses as subscription-plan usage subject
to your plan's limits, not a separate free allowance - see
[Anthropic](/providers/anthropic) for the current billing detail and links to
Anthropic's own support articles. For the most predictable server-side setup, use an
Anthropic API key instead.
</Accordion>
<Accordion title="Do you support Claude subscription auth (Claude Pro or Max)?">
Yes, via Claude CLI reuse. Anthropic's billing treatment of `claude -p`/Agent SDK usage
has changed over time; see [Anthropic](/providers/anthropic) for the current state and
dated links to Anthropic's support articles before relying on specific billing
behavior.
Anthropic setup-token auth is also still a supported token path, but OpenClaw prefers
Claude CLI reuse and `claude -p` when available. For production or multi-user
workloads, an Anthropic API key remains the safer, more predictable choice. Other
subscription-style hosted options: [OpenAI](/providers/openai), [Qwen Cloud](/providers/qwen),
[MiniMax](/providers/minimax), [Z.AI (GLM)](/providers/zai).
</Accordion>
</AccordionGroup>
<a id="why-am-i-seeing-http-429-ratelimiterror-from-anthropic"></a>
<AccordionGroup>
<Accordion title="Why am I seeing HTTP 429 rate_limit_error from Anthropic?">
Your **Anthropic quota/rate limit** is exhausted for the current window. On **Claude
CLI**, wait for the window to reset or upgrade your plan. On an **Anthropic API key**,
check usage/billing in the Anthropic Console and raise limits as needed.
If the message is specifically `Extra usage is required for long context requests`,
the request is trying to use Anthropic's 1M context window (a GA-capable 1M Claude 4.x
model, or legacy `params.context1m: true` config), and your current credential is not
eligible for long-context billing.
Set a **fallback model** so OpenClaw keeps replying while a provider is rate-limited.
See [Models](/cli/models), [OAuth](/concepts/oauth), and
[Anthropic 429 extra usage required for long context](/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context).
</Accordion>
<Accordion title="Is AWS Bedrock supported?">
Yes. OpenClaw has a bundled **Amazon Bedrock (Converse)** provider. With AWS env
markers present (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, `AWS_BEARER_TOKEN_BEDROCK`),
OpenClaw auto-enables the implicit Bedrock provider for model discovery; otherwise
set `plugins.entries.amazon-bedrock.config.discovery.enabled: true` or add a manual
provider entry. See [Amazon Bedrock](/providers/bedrock) and [Model providers](/providers/models).
An OpenAI-compatible proxy in front of Bedrock is still a valid option if you prefer a managed key flow.
</Accordion>
<Accordion title="How does Codex auth work?">
OpenClaw supports **OpenAI Codex** via OAuth (ChatGPT sign-in). Use `openai/gpt-5.5`
for the default setup: ChatGPT/Codex subscription auth plus native Codex app-server
execution. Legacy Codex-prefixed model refs are legacy config repaired by
`openclaw doctor --fix`. Direct OpenAI API-key access remains available for non-agent
OpenAI API surfaces and, through an ordered `openai` API-key profile, for agent models
too. See [Model providers](/concepts/model-providers) and [Onboarding (CLI)](/start/wizard).
</Accordion>
<Accordion title="Why does OpenClaw still mention legacy OpenAI Codex prefix?">
`openai` is the current provider and auth-profile id for both OpenAI API keys and
ChatGPT/Codex OAuth - OpenAI Codex is folded into it. You may still see a legacy
`openai-codex` prefix in older config and migration warnings:
- `openai/gpt-5.5` = ChatGPT/Codex subscription auth with native Codex runtime for agent turns.
- Legacy `openai-codex/*` model refs = legacy route repaired by `openclaw doctor --fix`.
- `openai/gpt-5.5` plus an ordered `openai` API-key profile = API-key auth for an OpenAI agent model.
- Legacy `openai-codex` auth profile ids = legacy ids migrated by `openclaw doctor --fix`.
Want direct OpenAI Platform billing? Set `OPENAI_API_KEY`. Want ChatGPT/Codex
subscription auth? Run `openclaw models auth login --provider openai`. Keep the model
ref as `openai/gpt-5.5`; legacy Codex-prefixed refs are what `openclaw doctor --fix` rewrites.
</Accordion>
<Accordion title="Why can Codex OAuth limits differ from ChatGPT web?">
Codex OAuth uses OpenAI-managed, plan-dependent quota windows that can differ from the
ChatGPT website/app experience, even on the same account.
`openclaw models status` shows the currently visible provider usage/quota windows, but
does not invent or normalize ChatGPT-web entitlements into direct API access. For the
direct OpenAI Platform billing/limit path, use `openai/*` with an API key.
</Accordion>
<Accordion title="Do you support OpenAI subscription auth (Codex OAuth)?">
Yes, fully. OpenAI explicitly allows subscription OAuth usage in external
tools/workflows like OpenClaw. Onboarding can run the OAuth flow for you.
See [OAuth](/concepts/oauth), [Model providers](/concepts/model-providers), and [Onboarding (CLI)](/start/wizard).
</Accordion>
<Accordion title="How do I set up Gemini CLI OAuth?">
Gemini CLI uses a **plugin auth flow**, not a client id or secret in `openclaw.json`.
1. Install Gemini CLI locally so `gemini` is on `PATH`:
- Homebrew: `brew install gemini-cli`
- npm: `npm install -g @google/gemini-cli`
2. Enable the plugin: `openclaw plugins enable google`
3. Login: `openclaw models auth login --provider google-gemini-cli --set-default`
4. Default model after login: `google/gemini-3.1-pro-preview` (runtime `google-gemini-cli`)
5. Requests failing after login? Set `GOOGLE_CLOUD_PROJECT` or `GOOGLE_CLOUD_PROJECT_ID` on the gateway host and retry.
OAuth tokens are stored in auth profiles on the gateway host. Details: [Google](/providers/google), [Model providers](/concepts/model-providers).
</Accordion>
<Accordion title="Is a local model OK for casual chats?">
Usually no. OpenClaw needs large context + strong safety; small cards truncate context
and skip provider-side safety filters. If you must, run the **largest** model build you
can locally (LM Studio) - see [Local models](/gateway/local-models). Smaller/quantized
models raise prompt-injection risk - see [Security](/gateway/security).
</Accordion>
<Accordion title="How do I keep hosted model traffic in a specific region?">
Pick region-pinned endpoints. OpenRouter exposes US-hosted options for MiniMax, Kimi,
and GLM; choose the US-hosted variant to keep data in-region. You can still list
Anthropic/OpenAI alongside these with `models.mode: "merge"` so fallbacks stay
available while respecting the regioned provider you select.
</Accordion>
<Accordion title="Do I have to buy a Mac Mini to install this?">
No. OpenClaw runs on macOS or Linux (Windows via WSL2). A Mac mini is a popular
always-on host choice, but a small VPS, home server, or Raspberry Pi-class box works too.
You only need a Mac **for macOS-only tools**. For iMessage, use [iMessage](/channels/imessage)
with `imsg` on any Mac signed into Messages - if the Gateway runs on Linux or elsewhere,
set `channels.imessage.cliPath` to an SSH wrapper that runs `imsg` on that Mac. For other
macOS-only tools, run the Gateway on a Mac or pair a macOS node.
Docs: [iMessage](/channels/imessage), [Nodes](/nodes), [Mac remote mode](/platforms/mac/remote).
</Accordion>
<Accordion title="Do I need a Mac mini for iMessage support?">
You need **some macOS device** signed into Messages - not necessarily a Mac mini, any
Mac works. Use [iMessage](/channels/imessage) with `imsg`; the Gateway can run on that
Mac, or elsewhere with an SSH wrapper `cliPath`.
Common setups:
- Gateway on Linux/VPS, `channels.imessage.cliPath` set to an SSH wrapper that runs `imsg` on a Mac signed into Messages.
- Everything on one Mac for the simplest single-machine setup.
Docs: [iMessage](/channels/imessage), [Nodes](/nodes), [Mac remote mode](/platforms/mac/remote).
</Accordion>
<Accordion title="If I buy a Mac mini to run OpenClaw, can I connect it to my MacBook Pro?">
Yes. The **Mac mini can run the Gateway**, and your MacBook Pro connects as a **node**
(companion device). Nodes do not run the Gateway - they add capabilities like
screen/camera/canvas and `system.run` on that device.
Common pattern: Gateway on the always-on Mac mini; MacBook Pro runs the macOS app or a
node host and pairs to the Gateway. Check with `openclaw nodes status` / `openclaw nodes list`.
Docs: [Nodes](/nodes), [Nodes CLI](/cli/nodes).
</Accordion>
<Accordion title="Can I use Bun?">
Not recommended - Bun has runtime bugs, especially with WhatsApp and Telegram. Use
**Node** for stable gateways. If you still want to experiment, do it on a
non-production gateway without WhatsApp/Telegram.
</Accordion>
<Accordion title="Telegram: what goes in allowFrom?">
`channels.telegram.allowFrom` is the **human sender's Telegram user ID** (numeric),
not the bot username. Setup asks for numeric user IDs only; `openclaw doctor --fix`
can try to resolve legacy `@username` entries.
Safer (no third-party bot): DM your bot, run `openclaw logs --follow`, read `from.id`.
Official Bot API: DM your bot, call `https://api.telegram.org/bot<bot_token>/getUpdates`, read `message.from.id`.
Third-party (less private): DM `@userinfobot` or `@getidsbot`.
See [Telegram access control](/channels/telegram#access-control-and-activation).
</Accordion>
<Accordion title="Can multiple people use one WhatsApp number with different OpenClaw instances?">
Yes, via **multi-agent routing**. Bind each sender's WhatsApp DM (`peer: { kind: "direct", id: "+15551234567" }`) to a different `agentId`, giving each person their own workspace and session store. Replies still come from the **same WhatsApp account**; DM access control (`channels.whatsapp.dmPolicy` / `channels.whatsapp.allowFrom`) is global per account. See [Multi-Agent Routing](/concepts/multi-agent) and [WhatsApp](/channels/whatsapp).
</Accordion>
<Accordion title='Can I run a "fast chat" agent and an "Opus for coding" agent?'>
Yes. Use multi-agent routing: give each agent its own default model, then bind inbound
routes (provider account or specific peers) to each agent. Example config:
[Multi-Agent Routing](/concepts/multi-agent). See also [Models](/concepts/models) and
[Configuration](/gateway/configuration).
</Accordion>
<Accordion title="Does Homebrew work on Linux?">
Yes, via Linuxbrew:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
brew install <formula>
```
Running OpenClaw via systemd: make sure the service PATH includes
`/home/linuxbrew/.linuxbrew/bin` (or your brew prefix) so `brew`-installed tools
resolve in non-login shells. Recent builds also prepend common user bin dirs on Linux
systemd services (for example `~/.local/bin`, `~/.npm-global/bin`,
`~/.local/share/pnpm`, `~/.bun/bin`) and honor `PNPM_HOME`, `NPM_CONFIG_PREFIX`,
`BUN_INSTALL`, `VOLTA_HOME`, `ASDF_DATA_DIR`, `NVM_DIR`, and `FNM_DIR` when set.
</Accordion>
<Accordion title="Difference between the hackable git install and npm install">
- **Hackable (git) install:** full source checkout, editable, best for contributors. You build locally and can patch code/docs.
- **npm install:** global CLI install, no repo, best for "just run it." Updates come from npm dist-tags.
Docs: [Getting started](/start/getting-started), [Updating](/install/updating).
</Accordion>
<Accordion title="Can I switch between npm and git installs later?">
Yes, with `openclaw update --channel ...` on an existing install. This does **not
delete your data** - only the OpenClaw code install changes. State (`~/.openclaw`) and
workspace (`~/.openclaw/workspace`) stay untouched.
npm to git:
```bash
openclaw update --channel dev
```
git to npm:
```bash
openclaw update --channel stable
```
Add `--dry-run` to preview the planned mode switch first. The updater runs Doctor
follow-ups, refreshes plugin sources for the target channel, and restarts the gateway
unless you pass `--no-restart`.
The installer can force either mode too:
```bash
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method npm
```
Backup tips: [Where things live on disk](/help/faq#where-things-live-on-disk).
</Accordion>
<Accordion title="Should I run the Gateway on my laptop or a VPS?">
Want 24/7 reliability? Use a **VPS**. Want the lowest friction and you are OK with
sleep/restarts? Run it locally.
**Laptop (local Gateway)**
- **Pros:** no server cost, direct access to local files, a live browser window.
- **Cons:** sleep/network drops disconnect it, OS updates/reboots interrupt it, must stay awake.
**VPS / cloud**
- **Pros:** always-on, stable network, no laptop sleep issues, easier to keep running.
- **Cons:** often headless (use screenshots), remote file access only, SSH needed for updates.
WhatsApp/Telegram/Slack/Mattermost/Discord all work fine from a VPS - the real
trade-off is headless browser vs a visible window. See [Browser](/tools/browser).
Default recommendation: VPS if you have had gateway disconnects before; local is great
when you are actively using the Mac and want local file access or visible-browser UI
automation.
</Accordion>
<Accordion title="How important is it to run OpenClaw on a dedicated machine?">
Not required, but recommended for reliability and isolation.
- **Dedicated host (VPS/Mac mini/Raspberry Pi):** always-on, fewer sleep/reboot interruptions, cleaner permissions, easier to keep running.
- **Shared laptop/desktop:** fine for testing and active use, but expect pauses when the machine sleeps or updates.
Best of both worlds: keep the Gateway on a dedicated host and pair your laptop as a
**node** for local screen/camera/exec tools. See [Nodes](/nodes) and [Security](/gateway/security).
</Accordion>
<Accordion title="What are the minimum VPS requirements and recommended OS?">
- **Absolute minimum:** 1 vCPU, 1 GB RAM, ~500 MB disk.
- **Recommended:** 1-2 vCPU, 2 GB+ RAM for headroom (logs, media, multiple channels). Node tools and browser automation can be resource hungry.
OS: **Ubuntu LTS** (or any modern Debian/Ubuntu) - the best-tested Linux install path.
Docs: [Linux](/platforms/linux), [VPS hosting](/vps).
</Accordion>
<Accordion title="Can I run OpenClaw in a VM and what are the requirements?">
Yes. Treat a VM like a VPS: it needs to be always on, reachable, and have enough RAM
for the Gateway and any channels you enable.
- **Absolute minimum:** 1 vCPU, 1 GB RAM.
- **Recommended:** 2 GB+ RAM for multiple channels, browser automation, or media tools.
- **OS:** Ubuntu LTS or another modern Debian/Ubuntu.
On Windows, use **Windows Hub** for desktop setup, or WSL2 for a Linux-style Gateway VM
with broad tooling compatibility. See [Windows](/platforms/windows), [VPS hosting](/vps).
Running macOS in a VM: see [macOS VM](/install/macos-vm).
</Accordion>
</AccordionGroup>
## Related
- [FAQ](/help/faq) - the main FAQ (models, sessions, gateway, security, more)
- [Install overview](/install)
- [Getting started](/start/getting-started)
- [Troubleshooting](/help/troubleshooting)

517
docs/help/faq-models.md Normal file
View File

@@ -0,0 +1,517 @@
---
summary: "FAQ: model defaults, selection, aliases, switching, failover, and auth profiles"
read_when:
- Choosing or switching models, configuring aliases
- Debugging model failover / "All models failed"
- Understanding auth profiles and how to manage them
title: "FAQ: models and auth"
sidebarTitle: "Models FAQ"
---
Model- and auth-profile Q&A. For setup, sessions, gateway, channels, and
troubleshooting, see the main [FAQ](/help/faq).
## Models: defaults, selection, aliases, switching
<AccordionGroup>
<Accordion title='What is the "default model"?'>
Set with:
```text
agents.defaults.model.primary
```
Models are `provider/model` refs (example: `openai/gpt-5.5`,
`anthropic/claude-sonnet-4-6`). Always set `provider/model` explicitly. If
you omit the provider, OpenClaw tries an alias match first, then a unique
configured-provider match for that model id, then falls back to the
configured default provider (deprecated compatibility path). If that
provider no longer has the configured default model, OpenClaw falls back
to the first configured provider/model instead of a stale default.
</Accordion>
<Accordion title="What model do you recommend?">
Use the strongest latest-generation model your provider stack offers,
especially for tool-enabled or untrusted-input agents — weaker or
over-quantized models are more vulnerable to prompt injection and unsafe
behavior (see [Security](/gateway/security)). Route cheaper models to
routine/low-stakes chat by agent role.
Route models per agent and use sub-agents to parallelize long tasks (each
sub-agent consumes its own tokens). See [Models](/concepts/models),
[Sub-agents](/tools/subagents), [MiniMax](/providers/minimax), and
[Local models](/gateway/local-models).
</Accordion>
<Accordion title="How do I switch models without wiping my config?">
Change only the model fields — avoid full config replaces.
- `/model` in chat (per-session, see [Slash commands](/tools/slash-commands))
- `openclaw models set ...` (updates just model config)
- `openclaw configure --section model` (interactive)
- edit `agents.defaults.model` in `~/.openclaw/openclaw.json` directly
For RPC edits, inspect with `config.schema.lookup` first (normalized
path, shallow schema docs, child summaries), then prefer `config.patch`
over `config.apply` with a partial object. If you did overwrite config,
restore from backup or run `openclaw doctor` to repair.
Docs: [Models](/concepts/models), [Configure](/cli/configure),
[Config](/cli/config), [Doctor](/gateway/doctor).
</Accordion>
<Accordion title="Can I use self-hosted models (llama.cpp, vLLM, Ollama)?">
Yes — Ollama is the easiest path. Quick setup:
1. Install Ollama from `https://ollama.com/download`
2. Pull a local model, e.g. `ollama pull gemma4`
3. For cloud models too, run `ollama signin`
4. Run `openclaw onboard`, choose `Ollama`, then `Local` or `Cloud + Local`
`Cloud + Local` gives you cloud models plus your local Ollama models;
cloud models such as `kimi-k2.5:cloud` need no local pull. To switch
manually: `openclaw models list`, then `openclaw models set ollama/<model>`.
Smaller/heavily quantized models are more vulnerable to prompt injection.
Use large models for any bot with tool access; if you use small models
anyway, enable sandboxing and strict tool allowlists.
Docs: [Ollama](/providers/ollama), [Local models](/gateway/local-models),
[Model providers](/concepts/model-providers), [Security](/gateway/security),
[Sandboxing](/gateway/sandboxing).
</Accordion>
<Accordion title="How do I switch models on the fly (without restarting)?">
Send `/model <name>` as a standalone message. See
[Slash commands](/tools/slash-commands) for the
full command list, including the numbered picker (`/model`, `/model
list`, `/model 3`), `/model default` to clear a session override, and
`/model status` for endpoint/API-mode detail.
Force a specific auth profile per session with `@profile`:
```text
/model opus@anthropic:default
/model opus@anthropic:work
```
To unpin a profile set with `@profile`, re-run `/model` without the
suffix (e.g. `/model anthropic/claude-opus-4-6`), or pick the default from
`/model`. Use `/model status` to confirm the active auth profile.
</Accordion>
<Accordion title="If two providers expose the same model id, which one does /model use?">
`/model provider/model` selects that exact provider route. For example,
`qianfan/deepseek-v4-flash` and `deepseek/deepseek-v4-flash` are different
refs even though the model id matches — OpenClaw does not silently switch
providers on a bare id match.
A user-selected `/model` ref is strict for fallback: if that
provider/model becomes unavailable, the reply fails visibly instead of
falling back to `agents.defaults.model.fallbacks`. Configured fallback
chains still apply to configured defaults, cron job primaries, and
auto-selected fallback state. When a non-session-override run is allowed
to use fallback, OpenClaw tries the requested provider/model first, then
configured fallbacks, then the configured primary — so duplicate bare
model ids never jump straight back to the default provider.
See [Models](/concepts/models) and [Model failover](/concepts/model-failover).
</Accordion>
<Accordion title="Can I use GPT 5.5 for daily tasks and Codex 5.5 for coding?">
Yes — model choice and runtime choice are separate:
- **Native Codex coding agent:** set `agents.defaults.model.primary` to
`openai/gpt-5.5`. Sign in with `openclaw models auth login --provider
openai` for ChatGPT/Codex subscription auth.
- **Direct OpenAI API tasks outside the agent loop:** configure
`OPENAI_API_KEY` for images, embeddings, speech, realtime, and other
non-agent OpenAI API surfaces.
- **OpenAI agent API-key auth:** `/model openai/gpt-5.5` with an ordered
`openai` API-key profile.
- **Sub-agents:** route coding tasks to a Codex-focused agent with its
own `openai/gpt-5.5` model.
See [Models](/concepts/models) and [Slash commands](/tools/slash-commands).
</Accordion>
<Accordion title="How do I configure fast mode for GPT 5.5?">
- **Per session:** send `/fast on` while using `openai/gpt-5.5`.
- **Per model default:** set
`agents.defaults.models["openai/gpt-5.5"].params.fastMode` to `true`.
- **Automatic cutoff:** `/fast auto` or `params.fastMode: "auto"` runs new
model calls fast until the cutoff, then runs later retry, fallback,
tool-result, or continuation calls without fast mode. Cutoff defaults to
60 seconds; override with `params.fastAutoOnSeconds` on the model.
```json5
{
agents: {
defaults: {
models: {
"openai/gpt-5.5": {
params: {
fastMode: "auto",
fastAutoOnSeconds: 30,
},
},
},
},
},
}
```
Fast mode maps to `service_tier = "priority"` on native OpenAI Responses
requests; existing `service_tier` values are preserved and fast mode does
not rewrite `reasoning` or `text.verbosity`. Session `/fast` overrides beat
config defaults.
See [Thinking and fast mode](/tools/thinking) and the Fast mode section
under Advanced configuration on the [OpenAI](/providers/openai) provider
page.
</Accordion>
<Accordion title='Why do I see "Model ... is not allowed" and then no reply?'>
If `agents.defaults.models` is set, it becomes the **allowlist** for
`/model` and session overrides. Picking a model outside that list returns
this instead of a normal reply:
```text
Model "provider/model" is not allowed. Use /models to list providers, or /models <provider> to list models.
Add it with: openclaw config set agents.defaults.models '{"provider/model":{}}' --strict-json --merge
```
Fix: add the exact model to `agents.defaults.models`, add a provider
wildcard such as `"provider/*": {}` for dynamic catalogs, remove the
allowlist, or pick a model from `/model list`. If the command also
included `--runtime codex`, update the allowlist first, then retry the
same `/model provider/model --runtime codex` command.
</Accordion>
<Accordion title='Why do I see "Unknown model: minimax/MiniMax-M3"?'>
If you're on an older OpenClaw release, upgrade first (or run from source
`main`) and restart the gateway — `MiniMax-M3` may not be in your
installed release's catalog yet. Otherwise the MiniMax provider is not
configured (no provider entry or auth profile found), so the model can't
resolve. See the Troubleshooting section on the
[MiniMax](/providers/minimax) provider page for the full fix checklist,
provider/model id table, and config-block example.
</Accordion>
<Accordion title="Can I use MiniMax as my default and OpenAI for complex tasks?">
Yes. Use MiniMax as the default and switch models per session — fallbacks
are for errors, not "hard tasks", so use `/model` or a separate agent.
**Option A: switch per session**
```json5
{
env: { MINIMAX_API_KEY: "sk-...", OPENAI_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "minimax/MiniMax-M3" },
models: {
"minimax/MiniMax-M3": { alias: "minimax" },
"openai/gpt-5.5": { alias: "gpt" },
},
},
},
}
```
Then `/model gpt`.
**Option B: separate agents** — Agent A defaults to MiniMax, Agent B
defaults to OpenAI; route by agent or use `/agent` to switch.
Docs: [Models](/concepts/models), [Multi-Agent Routing](/concepts/multi-agent),
[MiniMax](/providers/minimax), [OpenAI](/providers/openai).
</Accordion>
<Accordion title="Are opus / sonnet / gpt built-in shortcuts?">
Yes — built-in shorthands, applied only when the target model exists in
`agents.defaults.models`:
| Alias | Resolves to |
| --- | --- |
| `opus` | `anthropic/claude-opus-4-8` |
| `sonnet` | `anthropic/claude-sonnet-4-6` |
| `gpt` | `openai/gpt-5.4` |
| `gpt-mini` | `openai/gpt-5.4-mini` |
| `gpt-nano` | `openai/gpt-5.4-nano` |
| `gemini` | `google/gemini-3.1-pro-preview` |
| `gemini-flash` | `google/gemini-3-flash-preview` |
| `gemini-flash-lite` | `google/gemini-3.1-flash-lite` |
Your own alias with the same name overrides the built-in one.
</Accordion>
<Accordion title="How do I define/override model shortcuts (aliases)?">
Aliases live at `agents.defaults.models.<modelId>.alias`:
```json5
{
agents: {
defaults: {
model: { primary: "anthropic/claude-opus-4-6" },
models: {
"anthropic/claude-opus-4-6": { alias: "opus" },
"anthropic/claude-sonnet-4-6": { alias: "sonnet" },
},
},
},
}
```
Then `/model sonnet` (or `/<alias>` when supported) resolves to that
model id.
</Accordion>
<Accordion title="How do I add models from other providers like OpenRouter or Z.AI?">
OpenRouter (pay-per-token; many models):
```json5
{
agents: {
defaults: {
model: { primary: "openrouter/anthropic/claude-sonnet-4-6" },
models: { "openrouter/anthropic/claude-sonnet-4-6": {} },
},
},
env: { OPENROUTER_API_KEY: "sk-or-..." },
}
```
Z.AI (GLM models):
```json5
{
agents: {
defaults: {
model: { primary: "zai/glm-5.1" },
models: { "zai/glm-5.1": {} },
},
},
env: { ZAI_API_KEY: "..." },
}
```
Missing provider key for a referenced provider/model raises a runtime
auth error (e.g. `No API key found for provider "zai"`).
**No API key found for provider after adding a new agent**
A new agent has an empty auth store — auth is per-agent, stored at:
```text
~/.openclaw/agents/<agentId>/agent/auth-profiles.json
```
Fix: run `openclaw agents add <id>` and configure auth in the wizard, or
copy only portable static `api_key`/`token` profiles from the main
agent's store. For OAuth, sign in from the new agent when it needs its
own account. See [Multi-Agent Routing](/concepts/multi-agent) for the
full `agentDir` reuse and credential-sharing rules — never reuse
`agentDir` across agents.
</Accordion>
</AccordionGroup>
## Model failover and "All models failed"
<AccordionGroup>
<Accordion title="How does failover work?">
Two stages:
1. **Auth profile rotation** within the same provider.
2. **Model fallback** to the next model in `agents.defaults.model.fallbacks`.
Cooldowns apply to failing profiles (exponential backoff), so OpenClaw
keeps responding when a provider is rate-limited or temporarily failing.
The rate-limit bucket covers more than plain `429`: `Too many concurrent
requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai
... quota limit exceeded`, `resource exhausted`, and periodic
usage-window limits (`weekly/monthly limit reached`) all count as
failover-worthy rate limits.
Billing responses aren't always `402`, and some `402`s stay in the
transient/rate-limit bucket rather than the billing lane. Explicit
billing text on `401`/`403` can still route to billing; provider-specific
text matchers (e.g. OpenRouter `Key limit exceeded`) stay scoped to their
own provider. A `402` that reads like a retryable usage-window or
org/workspace spend limit (`daily limit reached, resets tomorrow`,
`organization spending limit exceeded`) is treated as `rate_limit`, not a
long billing disable.
Context-overflow errors stay off the fallback path entirely — signatures
like `request_too_large`, `input exceeds the maximum number of tokens`,
`input token count exceeds the maximum number of input tokens`, `input is
too long for the model`, or `ollama error: context length exceeded` go to
compaction/retry instead of advancing model fallback.
Generic server-error text is narrower than "anything with unknown/error
in it". Provider-scoped transient shapes that do count as failover
signals: Anthropic bare `An unknown error occurred`, OpenRouter bare
`Provider returned error`, stop-reason errors like `Unhandled stop reason:
error`, JSON `api_error` payloads with transient server text (`internal
server error`, `unknown error, 520`, `upstream error`, `backend error`),
and provider-busy errors like `ModelNotReadyException` when the provider
context matches. Generic internal fallback text like `LLM request failed
with an unknown error.` stays conservative and does not trigger fallback
by itself.
</Accordion>
<Accordion title='What does "No credentials found for profile anthropic:default" mean?'>
The auth profile id `anthropic:default` has no credentials in the
expected auth store.
**Fix checklist:**
- Confirm where profiles live — current:
`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`; legacy:
`~/.openclaw/agent/*` (migrated by `openclaw doctor`).
- Confirm the Gateway loads your env var. `ANTHROPIC_API_KEY` set only in
your shell won't reach a Gateway run via systemd/launchd — put it in
`~/.openclaw/.env` or enable `env.shellEnv`.
- Confirm you're editing the right agent — multi-agent setups have
multiple `auth-profiles.json` files.
- Run `openclaw models status` to see configured models and provider
auth state.
**For "No credentials found for profile anthropic" (no email suffix):**
The run is pinned to an Anthropic profile the Gateway can't find.
- Use Claude CLI: run `openclaw models auth login --provider anthropic
--method cli --set-default` on the gateway host.
- Prefer an API key instead: put `ANTHROPIC_API_KEY` in
`~/.openclaw/.env` on the gateway host, then clear any pinned order
that forces the missing profile:
```bash
openclaw models auth order clear --provider anthropic
```
- Remote mode: auth profiles live on the gateway machine, not your
laptop — confirm you're running commands there.
</Accordion>
<Accordion title="Why did it also try Google Gemini and fail?">
If your model config includes Google Gemini as a fallback (or you
switched to a Gemini shorthand), OpenClaw tries it during fallback. No
Google credentials configured gives `No API key found for provider
"google"`. Fix: add Google auth, or remove Google models from
`agents.defaults.model.fallbacks`/aliases.
**LLM request rejected: thinking signature required (Google Antigravity)**
Cause: session history has thinking blocks without signatures (often
from an aborted/partial stream); Google Antigravity requires signatures
on thinking blocks. OpenClaw strips unsigned thinking blocks for Google
Antigravity Claude; if it still appears, start a new session or set
`/thinking off` for that agent.
</Accordion>
</AccordionGroup>
## Auth profiles: what they are and how to manage them
Related: [/concepts/oauth](/concepts/oauth) (OAuth flows, token storage, multi-account patterns)
<AccordionGroup>
<Accordion title="What is an auth profile?">
A named credential record (OAuth or API key) tied to a provider, stored
at:
```text
~/.openclaw/agents/<agentId>/agent/auth-profiles.json
```
Inspect saved profiles without dumping secrets: `openclaw models auth
list` (optionally `--provider <id>` or `--json`). See
[Models CLI](/cli/models#auth-profiles).
</Accordion>
<Accordion title="What are typical profile IDs?">
Provider-prefixed: `anthropic:default` (common when no email identity
exists), `anthropic:<email>` for OAuth identities, or a custom id you
choose (e.g. `anthropic:work`).
</Accordion>
<Accordion title="Can I control which auth profile is tried first?">
Yes. `auth.order.<provider>` config sets rotation order per provider
(metadata only — no secrets stored).
OpenClaw may skip a profile in a short **cooldown** (rate limits,
timeouts, auth failures) or a longer **disabled** state
(billing/insufficient credits). Inspect with `openclaw models status
--json` and check `auth.unusableProfiles`. Tune with
`auth.cooldowns.billingBackoffHours*`. Rate-limit cooldowns can be
model-scoped — a profile cooling down for one model can still serve a
sibling model on the same provider; billing/disabled windows block the
whole profile.
Set a per-agent order override (stored in that agent's `auth-state.json`):
```bash
# Defaults to the configured default agent (omit --agent)
openclaw models auth order get --provider anthropic
# Lock rotation to a single profile
openclaw models auth order set --provider anthropic anthropic:default
# Or set an explicit order (fallback within provider)
openclaw models auth order set --provider anthropic anthropic:work anthropic:default
# Clear override (fall back to config auth.order / round-robin)
openclaw models auth order clear --provider anthropic
# Target a specific agent
openclaw models auth order set --provider anthropic --agent main anthropic:default
```
Verify what will actually be tried: `openclaw models status --probe`. A
stored profile omitted from an explicit order reports
`excluded_by_auth_order` instead of being tried silently.
</Accordion>
<Accordion title="OAuth vs API key - what is the difference?">
- **OAuth / CLI login** often uses subscription access where the
provider supports it. For Anthropic, OpenClaw's Claude CLI backend
uses Claude Code `claude -p`, which Anthropic currently treats as
Agent SDK/programmatic usage drawing from subscription usage limits —
see [Anthropic](/providers/anthropic) for the current billing-pause
status and source links.
- **API keys** use pay-per-token billing.
The wizard supports Anthropic Claude CLI, OpenAI Codex OAuth, and API
keys.
</Accordion>
</AccordionGroup>
## Related
- [FAQ](/help/faq) — the main FAQ
- [FAQ — quick start and first-run setup](/help/faq-first-run)
- [Model selection](/concepts/model-providers)
- [Model failover](/concepts/model-failover)

1597
docs/help/faq.md Normal file

File diff suppressed because it is too large Load Diff

39
docs/help/index.md Normal file
View File

@@ -0,0 +1,39 @@
---
summary: "Help hub: common fixes, install sanity, and where to look when something breaks"
read_when:
- You are new and want a "what do I click/run" guide
- Something broke and you want the fastest path to a fix
title: "Help"
---
Fastest path to unstuck, by symptom:
- [Troubleshooting](/help/troubleshooting) - symptom-first decision tree
- [Debugging](/help/debugging) - watch mode, raw streams, dev profile
- [Install sanity](/install/node#troubleshooting) - Node / npm / PATH checks
- [Gateway troubleshooting](/gateway/troubleshooting) - gateway-specific issues
- [Doctor](/gateway/doctor) - `openclaw doctor`: health checks, config migrations, repair steps
## FAQ
- [FAQ](/help/faq) - day-to-day concepts and operational questions
- [First-run FAQ](/help/faq-first-run) - install, onboard, auth, subscriptions, early failures
- [Models FAQ](/help/faq-models) - model selection, failover, auth profiles
## Diagnostics
- [Environment variables](/help/environment) - where OpenClaw loads env vars and precedence
- [Diagnostics flags](/diagnostics/flags) - runtime diagnostics and verbose modes
- [Node + tsx crash](/debug/node-issue) - specific Node / tsx runtime crash scenarios
## Testing
- [Testing](/help/testing) - test suites and Docker runners
- [Update and plugin tests](/help/testing-updates-plugins) - package update, migration, and plugin install validation
- [Live tests](/help/testing-live) - network-touching provider and CLI smokes
## Community and meta
- [OpenClaw lore](/start/lore) - the story
- [Docs hubs](/start/hubs) - how this documentation is organized
- [Docs directory](/start/docs-directory) - full file map

61
docs/help/scripts.md Normal file
View File

@@ -0,0 +1,61 @@
---
summary: "Repository scripts: purpose, scope, and safety notes"
read_when:
- Running scripts from the repo
- Adding or changing scripts under ./scripts
title: "Scripts"
---
`scripts/` holds helper scripts for local workflows and ops tasks. Use these when a task is clearly tied to a script; otherwise prefer the CLI.
## Conventions
- Scripts are **optional** unless referenced in docs or release checklists.
- Prefer CLI surfaces when they exist (example: `openclaw models status --check`).
- Assume scripts are host-specific; read them before running on a new machine.
## Auth monitoring scripts
General model auth is covered in [Authentication](/gateway/authentication). The scripts below are a separate, optional system for monitoring a **Claude Code CLI subscription token** on a remote/headless host and re-authenticating from a phone:
- `scripts/setup-auth-system.sh` - one-time setup: checks current auth, helps generate a long-lived `claude setup-token`, and prints systemd/Termux install steps.
- `scripts/claude-auth-status.sh [full|json|simple]` - checks Claude Code + OpenClaw auth status.
- `scripts/auth-monitor.sh` - polls status and sends a notification (via OpenClaw send, and/or ntfy.sh) when the token nears expiry. Env: `WARN_HOURS` (default `2`), `NOTIFY_PHONE`, `NOTIFY_NTFY`. Run on a schedule via the bundled `scripts/systemd/openclaw-auth-monitor.{service,timer}` (every 30 minutes).
- `scripts/mobile-reauth.sh` - re-runs `claude setup-token` and prints URLs to open on a phone, for use over SSH from Termux.
- `scripts/termux-quick-auth.sh`, `scripts/termux-auth-widget.sh`, `scripts/termux-sync-widget.sh` - Termux:Widget scripts that SSH to the host, show a status toast, and open the re-auth console/instructions when auth has expired.
## GitHub read helper
Use `scripts/gh-read` when you want `gh` to use a GitHub App installation token for repo-scoped read calls while leaving normal `gh` on your personal login for write actions.
Required env:
- `OPENCLAW_GH_READ_APP_ID`
- `OPENCLAW_GH_READ_PRIVATE_KEY_FILE`
Optional env:
- `OPENCLAW_GH_READ_INSTALLATION_ID` when you want to skip repo-based installation lookup
- `OPENCLAW_GH_READ_PERMISSIONS` as a comma-separated override for the read permission subset to request
Repo resolution order:
- `gh ... -R owner/repo`
- `GH_REPO`
- `git remote origin`
Examples:
- `scripts/gh-read pr view 123`
- `scripts/gh-read run list -R openclaw/openclaw`
- `scripts/gh-read api repos/openclaw/openclaw/pulls/123`
## When adding scripts
- Keep scripts focused and documented.
- Add a short entry in the relevant doc (or create one if missing).
## Related
- [Testing](/help/testing)
- [Testing live](/help/testing-live)

615
docs/help/testing-live.md Normal file
View File

@@ -0,0 +1,615 @@
---
summary: "Live (network-touching) tests: model matrix, CLI backends, ACP, media providers, credentials"
read_when:
- Running live model matrix / CLI backend / ACP / media-provider smokes
- Debugging live-test credential resolution
- Adding a new provider-specific live test
title: "Testing: live suites"
sidebarTitle: "Live tests"
---
For quick start, QA runners, unit/integration suites, and Docker flows, see
[Testing](/help/testing). This page covers **live** (network-touching) tests:
model matrix, CLI backends, ACP, media providers, and credential handling.
## Live: local smoke commands
Export the needed provider key in the process environment before ad hoc live
checks.
Safe media smoke:
```bash
pnpm openclaw infer tts convert --local --json \
--text "OpenClaw live smoke." \
--output /tmp/openclaw-live-smoke.mp3
```
Safe voice-call readiness smoke:
```bash
pnpm openclaw voicecall setup --json
pnpm openclaw voicecall smoke --to "+15555550123"
```
`voicecall smoke` is a dry run unless `--yes` is also present; use `--yes` only
when you intend to place a real call. For Twilio, Telnyx, and Plivo, a
successful readiness check requires a public webhook URL - local/private
loopback URLs are rejected because those providers cannot reach them.
## Live: Android node capability sweep
- Test: `src/gateway/android-node.capabilities.live.test.ts`
- Script: `pnpm android:test:integration`
- Goal: invoke **every command currently advertised** by a connected Android node and assert command contract behavior.
- Scope:
- Preconditioned/manual setup (the suite does not install/run/pair the app).
- Command-by-command gateway `node.invoke` validation for the selected Android node.
- Required pre-setup:
- Android app already connected + paired to the gateway.
- App kept in foreground.
- Permissions/capture consent granted for capabilities you expect to pass.
- Optional target overrides:
- `OPENCLAW_ANDROID_NODE_ID` or `OPENCLAW_ANDROID_NODE_NAME`.
- `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`.
- Full Android setup details: [Android App](/platforms/android)
## Live: model smoke (profile keys)
Live model tests are split into two layers so failures are isolated:
- "Direct model" tells you whether the provider/model can answer at all with the given key.
- "Gateway smoke" tells you whether the full gateway+agent pipeline works for that model (sessions, history, tools, sandbox policy, etc.).
The curated model lists below live in `src/agents/live-model-filter.ts` and
change over time; treat the arrays there as the source of truth, not this
page.
MiniMax M3 uses `minimax/MiniMax-M3` as its default provider/model reference.
### Layer 1: Direct model completion (no gateway)
- Test: `src/agents/models.profiles.live.test.ts`
- Goal:
- Enumerate discovered models
- Use `getApiKeyForModel` to select models you have creds for
- Run a small completion per model (and targeted regressions where needed)
- How to enable:
- `pnpm test:live` (or `OPENCLAW_LIVE_TEST=1` if invoking Vitest directly)
- Set `OPENCLAW_LIVE_MODELS=modern`, `small`, or `all` (alias for `modern`) to actually run this suite; otherwise it skips, so `pnpm test:live` on its own stays focused on gateway smoke.
- How to select models:
- `OPENCLAW_LIVE_MODELS=modern` runs the curated high-signal priority list (see [Live: model matrix](#live-model-matrix-what-we-cover))
- `OPENCLAW_LIVE_MODELS=small` runs the curated small-model priority list
- `OPENCLAW_LIVE_MODELS=all` is an alias for `modern`
- or `OPENCLAW_LIVE_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,..."` (comma allowlist)
- Local Ollama small-model runs default to `http://127.0.0.1:11434`; set `OPENCLAW_LIVE_OLLAMA_BASE_URL` only for LAN, custom, or Ollama Cloud endpoints.
- Modern/all and small sweeps default to their curated-list length as a cap; set `OPENCLAW_LIVE_MAX_MODELS=0` for an exhaustive selected-profile sweep or a positive number for a smaller cap.
- Exhaustive sweeps use `OPENCLAW_LIVE_TEST_TIMEOUT_MS` for the whole direct-model test timeout. Default: 60 minutes.
- Direct-model probes run with 20-way parallelism by default; set `OPENCLAW_LIVE_MODEL_CONCURRENCY` to override.
- How to select providers:
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"` (comma allowlist)
- Where keys come from:
- By default: profile store and env fallbacks
- Set `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` to enforce **profile store** only
- Why this exists:
- Separates "provider API is broken / key is invalid" from "gateway agent pipeline is broken"
- Contains small, isolated regressions (example: OpenAI Responses/Codex Responses reasoning replay + tool-call flows)
### Layer 2: Gateway + dev agent smoke (what "@openclaw" actually does)
- Test: `src/gateway/gateway-models.profiles.live.test.ts`
- Goal:
- Spin up an in-process gateway
- Create/patch an `agent:dev:*` session (model override per run)
- Iterate models-with-keys and assert:
- "meaningful" response (no tools)
- a real tool invocation works (read probe)
- optional extra tool probes (exec+read probe)
- OpenAI regression paths (tool-call-only -> follow-up) keep working
- Probe details (so you can explain failures quickly):
- `read` probe: the test writes a nonce file in the workspace and asks the agent to `read` it and echo the nonce back.
- `exec+read` probe: the test asks the agent to `exec`-write a nonce into a temp file, then `read` it back.
- image probe: the test attaches a generated PNG (cat + randomized code) and expects the model to return `cat <CODE>`.
- Implementation reference: `src/gateway/gateway-models.profiles.live.test.ts` and `test/helpers/live-image-probe.ts`.
- How to enable:
- `pnpm test:live` (or `OPENCLAW_LIVE_TEST=1` if invoking Vitest directly)
- How to select models:
- Default: the curated high-signal (`modern`) priority list
- `OPENCLAW_LIVE_GATEWAY_MODELS=small` runs the curated small-model list through the full gateway+agent pipeline
- `OPENCLAW_LIVE_GATEWAY_MODELS=all` is an alias for `modern`
- Or set `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (or comma list) to narrow
- Modern/all and small gateway sweeps default to their curated-list length as a cap; set `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` for an exhaustive selected sweep or a positive number for a smaller cap.
- How to select providers (avoid "OpenRouter everything"):
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (comma allowlist)
- Tool + image probes are always on in this live test:
- `read` probe + `exec+read` probe (tool stress)
- image probe runs when the model advertises image input support
- Flow (high level):
- Test generates a tiny PNG with "CAT" + random code (`test/helpers/live-image-probe.ts`)
- Sends it via `agent` `attachments: [{ mimeType: "image/png", content: "<base64>" }]`
- Gateway parses attachments into `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`)
- Embedded agent forwards a multimodal user message to the model
- Assertion: reply contains `cat` + the code (OCR tolerance: minor mistakes allowed)
<Tip>
To see what you can test on your machine (and the exact `provider/model` ids), run:
```bash
openclaw models list
openclaw models list --json
```
</Tip>
## Live: CLI backend smoke (Claude, Gemini, or other local CLIs)
- Test: `src/gateway/gateway-cli-backend.live.test.ts`
- Goal: validate the Gateway + agent pipeline using a local CLI backend, without touching your default config.
- Backend-specific smoke defaults live with the owning plugin's `cli-backend.ts` definition.
- Enable:
- `pnpm test:live` (or `OPENCLAW_LIVE_TEST=1` if invoking Vitest directly)
- `OPENCLAW_LIVE_CLI_BACKEND=1`
- Defaults:
- Default provider/model: `claude-cli/claude-sonnet-4-6`
- Command/args/image behavior come from the owning CLI backend plugin metadata.
- Overrides (optional):
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="claude-cli/claude-sonnet-4-6"`
- `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/claude"`
- `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["-p","--output-format","json"]'`
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` to send a real image attachment (paths are injected into the prompt). Off by default in Docker recipes.
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` to pass image file paths as CLI args instead of prompt injection.
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (or `"list"`) to control how image args are passed when `IMAGE_ARG` is set.
- `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` to send a second turn and validate resume flow.
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=1` to opt into the Claude Sonnet -> Opus same-session continuity probe when the selected model supports a switch target. Off by default, including in Docker recipes.
- `OPENCLAW_LIVE_CLI_BACKEND_MCP_PROBE=1` to opt into the MCP/tool loopback probe. Off by default in Docker recipes.
Example:
```bash
OPENCLAW_LIVE_CLI_BACKEND=1 \
OPENCLAW_LIVE_CLI_BACKEND_MODEL="claude-cli/claude-sonnet-4-6" \
pnpm test:live src/gateway/gateway-cli-backend.live.test.ts
```
Cheap Gemini MCP config smoke:
```bash
OPENCLAW_LIVE_TEST=1 \
pnpm test:live src/agents/cli-runner/bundle-mcp.gemini.live.test.ts
```
This does not ask Gemini to generate a response. It writes the same system
settings OpenClaw gives Gemini, then runs `gemini --debug mcp list` to prove a
saved `transport: "streamable-http"` server is normalized to Gemini's HTTP MCP
shape and can connect to a local streamable-HTTP MCP server.
Docker recipe:
```bash
pnpm test:docker:live-cli-backend
```
Single-provider Docker recipes:
```bash
pnpm test:docker:live-cli-backend:claude
pnpm test:docker:live-cli-backend:claude-subscription
pnpm test:docker:live-cli-backend:gemini
```
Notes:
- The Docker runner lives at `scripts/test-live-cli-backend-docker.sh`.
- It runs the live CLI-backend smoke inside the repo Docker image as the non-root `node` user.
- It resolves CLI smoke metadata from the owning plugin, then installs the matching Linux CLI package (`@anthropic-ai/claude-code` or `@google/gemini-cli`) into a cached writable prefix at `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (default: `~/.cache/openclaw/docker-cli-tools`).
- `codex-cli` is no longer a bundled CLI backend; use `openai/*` with the Codex app-server runtime instead (see [Live: Codex app-server harness smoke](#live-codex-app-server-harness-smoke)).
- `pnpm test:docker:live-cli-backend:claude-subscription` requires portable Claude Code subscription OAuth through either `~/.claude/.credentials.json` with `claudeAiOauth.subscriptionType` or `CLAUDE_CODE_OAUTH_TOKEN` from `claude setup-token`. It first proves direct `claude -p` in Docker, then runs two Gateway CLI-backend turns without preserving Anthropic API-key env vars. This subscription lane disables the Claude MCP/tool and image probes by default because it consumes the signed-in subscription's usage limits and Anthropic can change Claude Agent SDK / `claude -p` billing and rate-limit behavior without an OpenClaw release.
- Claude and Gemini support the same probe set (text turn, image classification, MCP `cron` tool call, model-switch continuity) through the flags above, but none of those probes run by default - opt in per flag as needed.
## Live: APNs HTTP/2 proxy reachability
- Test: `src/infra/push-apns-http2.live.test.ts`
- Goal: tunnel through a local HTTP CONNECT proxy to Apple's sandbox APNs endpoint, send the APNs HTTP/2 validation request, and assert Apple's real `403 InvalidProviderToken` response comes back through the proxy path.
- Enable:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_APNS_REACHABILITY=1 pnpm test:live src/infra/push-apns-http2.live.test.ts`
- Optional timeout:
- `OPENCLAW_LIVE_APNS_TIMEOUT_MS=30000`
## Live: ACP bind smoke (`/acp spawn ... --bind here`)
- Test: `src/gateway/gateway-acp-bind.live.test.ts`
- Goal: validate the real ACP conversation-bind flow with a live ACP agent:
- send `/acp spawn <agent> --bind here`
- bind a synthetic message-channel conversation in place
- send a normal follow-up on that same conversation
- verify the follow-up lands in the bound ACP session transcript
- Enable:
- `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts`
- `OPENCLAW_LIVE_ACP_BIND=1`
- Defaults:
- ACP agents in Docker: `claude,codex,gemini`
- ACP agent for direct `pnpm test:live ...`: `claude`
- Synthetic channel: Slack DM-style conversation context
- ACP backend: `acpx`
- Overrides:
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=codex`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=droid`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENT=opencode`
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@<version>'`
- `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.5`
- `OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL=opencode/kimi-k2.6`
- `OPENCLAW_LIVE_ACP_BIND_IMAGE_PROBE=1` (or `on`/`true`/`yes`) to force the image probe on; any other value forces it off. Runs by default for every agent except `opencode`.
- `OPENCLAW_LIVE_ACP_BIND_REQUIRE_CRON=1`
- `OPENCLAW_LIVE_ACP_BIND_PARENT_MODEL=openai/gpt-5.5`
- Notes:
- This lane uses the gateway `chat.send` surface with admin-only synthetic originating-route fields so tests can attach message-channel context without pretending to deliver externally.
- When `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` is unset, the test uses the embedded `acpx` plugin's built-in agent registry for the selected ACP harness agent.
- Bound-session cron MCP creation is best-effort by default because external ACP harnesses can cancel MCP calls after the bind/image proof has passed; set `OPENCLAW_LIVE_ACP_BIND_REQUIRE_CRON=1` to make that post-bind cron probe strict.
Example:
```bash
OPENCLAW_LIVE_ACP_BIND=1 \
OPENCLAW_LIVE_ACP_BIND_AGENT=claude \
pnpm test:live src/gateway/gateway-acp-bind.live.test.ts
```
Docker recipe:
```bash
pnpm test:docker:live-acp-bind
```
Single-agent Docker recipes:
```bash
pnpm test:docker:live-acp-bind:claude
pnpm test:docker:live-acp-bind:codex
pnpm test:docker:live-acp-bind:droid
pnpm test:docker:live-acp-bind:gemini
pnpm test:docker:live-acp-bind:opencode
```
Docker notes:
- The Docker runner lives at `scripts/test-live-acp-bind-docker.sh`.
- By default, it runs the ACP bind smoke against the aggregate live CLI agents in sequence: `claude`, `codex`, then `gemini`.
- Use `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=droid`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini`, or `OPENCLAW_LIVE_ACP_BIND_AGENTS=opencode` to narrow the matrix.
- It stages the matching CLI auth material into the container, then installs the requested live CLI (`@anthropic-ai/claude-code`, `@openai/codex`, Factory Droid via `https://app.factory.ai/cli`, `@google/gemini-cli`, or `opencode-ai`) if missing. The ACP backend itself is the embedded `acpx/runtime` package from the official `acpx` plugin.
- The Droid Docker variant stages `~/.factory` for settings, forwards `FACTORY_API_KEY`, and requires that API key because local Factory OAuth/keyring auth is not portable into the container. It uses ACPX's built-in `droid exec --output-format acp` registry entry.
- The OpenCode Docker variant is a strict single-agent regression lane. It writes a temporary `OPENCODE_CONFIG_CONTENT` default model from `OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL` (default `opencode/kimi-k2.6`).
- Direct `acpx` CLI calls are only a manual/workaround path for comparing behavior outside the Gateway. The Docker ACP bind smoke exercises OpenClaw's embedded `acpx` runtime backend.
## Live: Codex app-server harness smoke
- Goal: validate the plugin-owned Codex harness through the normal gateway
`agent` method:
- load the bundled `codex` plugin
- select `openai/gpt-5.5`, which routes OpenAI agent turns through Codex by default
- send a first gateway agent turn to `openai/gpt-5.5` with the Codex harness selected
- send a second turn to the same OpenClaw session and verify the app-server
thread can resume
- run `/codex status` and `/codex models` through the same gateway command
path
- optionally run two Guardian-reviewed escalated shell probes: one benign
command that should be approved and one fake-secret upload that should be
denied so the agent asks back
- Test: `src/gateway/gateway-codex-harness.live.test.ts`
- Enable: `OPENCLAW_LIVE_CODEX_HARNESS=1`
- Default model: `openai/gpt-5.5`
- Optional image probe: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
- Optional MCP/tool probe: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
- Optional Guardian probe: `OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1`
- The smoke forces provider/model `agentRuntime.id: "codex"` so a broken Codex
harness cannot pass by silently falling back to OpenClaw.
- Auth: Codex app-server auth from the local Codex subscription login. Docker
smokes can also provide `OPENAI_API_KEY` for non-Codex probes when applicable,
plus optional copied `~/.codex/auth.json` and `~/.codex/config.toml`.
Local recipe:
```bash
OPENCLAW_LIVE_CODEX_HARNESS=1 \
OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_MODEL=openai/gpt-5.5 \
pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts
```
Docker recipe:
```bash
pnpm test:docker:live-codex-harness
```
Docker notes:
- The Docker runner lives at `scripts/test-live-codex-harness-docker.sh`.
- It passes `OPENAI_API_KEY`, copies Codex CLI auth files when present, installs
`@openai/codex` into a writable mounted npm
prefix, stages the source tree, then runs only the Codex-harness live test.
- Docker enables the image, MCP/tool, and Guardian probes by default. Set
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` or
`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0` or
`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0` when you need a narrower debug
run.
- Docker uses the same explicit Codex runtime config, so legacy aliases or OpenClaw
fallback cannot hide a Codex harness regression.
### Recommended live recipes
Narrow, explicit allowlists are fastest and least flaky:
- Single model, direct (no gateway):
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.5" pnpm test:live src/agents/models.profiles.live.test.ts`
- Small-model direct profile:
- `OPENCLAW_LIVE_MODELS=small pnpm test:live src/agents/models.profiles.live.test.ts`
- Small-model gateway profile:
- `OPENCLAW_LIVE_GATEWAY_MODELS=small pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Ollama Cloud API smoke:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_OLLAMA=1 OPENCLAW_LIVE_OLLAMA_BASE_URL=https://ollama.com OPENCLAW_LIVE_OLLAMA_MODEL=glm-5.1:cloud OPENCLAW_LIVE_OLLAMA_WEB_SEARCH=0 pnpm test:live -- extensions/ollama/ollama.live.test.ts`
- Single model, gateway smoke:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Tool calling across several providers:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Z.AI Coding Plan GLM-5.2 direct smoke:
- `ZAI_CODING_LIVE_TEST=1 pnpm test:live src/agents/zai.live.test.ts`
- Google focus (Gemini API key + Antigravity):
- Gemini (API key): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Antigravity (OAuth): `OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- Google adaptive thinking smoke (`qa manual` from the private QA CLI - requires `OPENCLAW_ENABLE_PRIVATE_QA_CLI=1` and a source checkout; see [QA overview](/concepts/qa-e2e-automation)):
- Gemini 3 dynamic default: `OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 pnpm openclaw qa manual --provider-mode live-frontier --model google/gemini-3.1-pro-preview --alt-model google/gemini-3.1-pro-preview --message '/think adaptive Reply exactly: GEMINI_ADAPTIVE_OK' --timeout-ms 180000`
- Gemini 2.5 dynamic budget: `OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 pnpm openclaw qa manual --provider-mode live-frontier --model google/gemini-2.5-flash --alt-model google/gemini-2.5-flash --message '/think adaptive Reply exactly: GEMINI25_ADAPTIVE_OK' --timeout-ms 180000`
Notes:
- `google/...` uses the Gemini API (API key).
- `google-antigravity/...` uses the Antigravity OAuth bridge (Cloud Code Assist-style agent endpoint).
- `google-gemini-cli/...` uses the local Gemini CLI on your machine (separate auth + tooling quirks).
- Gemini API vs Gemini CLI:
- API: OpenClaw calls Google's hosted Gemini API over HTTP (API key / profile auth); this is what most users mean by "Gemini".
- CLI: OpenClaw shells out to a local `gemini` binary; it has its own auth and can behave differently (streaming/tool support/version skew).
## Live: model matrix (what we cover)
Live is opt-in, so there is no fixed "CI model list." `OPENCLAW_LIVE_MODELS=modern` / `OPENCLAW_LIVE_GATEWAY_MODELS=modern` (and their `all` alias) run the curated priority list from `HIGH_SIGNAL_LIVE_MODEL_PRIORITY` in `src/agents/live-model-filter.ts`, in this priority order:
| Provider/model | Notes |
| --------------------------------------------- | ---------- |
| `anthropic/claude-opus-4-8` | |
| `anthropic/claude-sonnet-4-6` | |
| `anthropic/claude-opus-4-7` | |
| `google/gemini-3.1-pro-preview` | Gemini API |
| `google/gemini-3-flash-preview` | Gemini API |
| `moonshot/kimi-k2.7-code` | |
| `anthropic/claude-opus-4-6` | |
| `deepseek/deepseek-v4-flash` | |
| `deepseek/deepseek-v4-pro` | |
| `minimax/MiniMax-M3` | |
| `openai/gpt-5.5` | |
| `openrouter/openai/gpt-5.2-chat` | |
| `openrouter/minimax/minimax-m2.7` | |
| `opencode-go/glm-5` | |
| `openrouter/ai21/jamba-large-1.7` | |
| `xai/grok-4.3` | |
| `zai/glm-5.1` | |
| `fireworks/accounts/fireworks/models/glm-5p1` | |
| `minimax-portal/minimax-m3` | |
The curated **small-model** list (`OPENCLAW_LIVE_MODELS=small` / `OPENCLAW_LIVE_GATEWAY_MODELS=small`), from `SMALL_LIVE_MODEL_PRIORITY`:
| Provider/model |
| ---------------------------- |
| `lmstudio/qwen/qwen3.5-9b` |
| `vllm/qwen/qwen3-8b` |
| `sglang/qwen/qwen3-8b` |
| `ollama/gemma3:4b` |
| `openrouter/qwen/qwen3.5-9b` |
| `openrouter/z-ai/glm-5.1` |
| `openrouter/z-ai/glm-5` |
| `zai/glm-5.1` |
Notes on the modern list:
- `codex` and `codex-cli` providers are excluded from the default modern sweep (they cover CLI-backend/ACP behavior, tested separately above). `openai/gpt-5.5` itself routes through the Codex app-server harness by default; see [Live: Codex app-server harness smoke](#live-codex-app-server-harness-smoke).
- `fireworks`, `google`, `openrouter`, and `xai` only run their explicitly curated model ids in the modern sweep (no automatic "every model from this provider" expansion).
- Include at least one image-capable model (Claude/Gemini/OpenAI-family vision variants, etc.) in `OPENCLAW_LIVE_GATEWAY_MODELS` to exercise the image probe.
Run gateway smoke with tools + image across a hand-picked cross-provider set:
```bash
OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
```
Optional additional coverage outside the curated lists (nice to have, pick a "tools"-capable model you have enabled):
- Mistral: `mistral/...`
- Cerebras: `cerebras/...` (if you have access)
- LM Studio: `lmstudio/...` (local; tool calling depends on API mode)
### Aggregators / alternate gateways
If you have keys enabled, you can also test via:
- OpenRouter: `openrouter/...` (hundreds of models; use `openclaw models scan` to find tool+image capable candidates)
- OpenCode: `opencode/...` for Zen and `opencode-go/...` for Go (auth via `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`)
More providers you can include in the live matrix (if you have creds/config):
- Built-in: `anthropic`, `cerebras`, `github-copilot`, `google`, `google-antigravity`, `google-gemini-cli`, `google-vertex`, `groq`, `mistral`, `openai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `zai`
- Via `models.providers` (custom endpoints): `minimax` (cloud/API), plus any OpenAI/Anthropic-compatible proxy (LM Studio, vLLM, LiteLLM, etc.)
<Tip>
Do not hardcode "all models" in docs. The authoritative list is whatever `discoverModels(...)` returns on your machine plus whatever keys are available.
</Tip>
## Credentials (never commit)
Live tests discover credentials the same way the CLI does. Practical implications:
- If the CLI works, live tests should find the same keys.
- If a live test says "no creds", debug the same way you'd debug `openclaw models list` / model selection.
- Per-agent auth profiles: `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (this is what "profile keys" means in the live tests)
- Config: `~/.openclaw/openclaw.json` (or `OPENCLAW_CONFIG_PATH`)
- Legacy OAuth dir: `~/.openclaw/credentials/` (copied into the staged live home when present, but not the main profile-key store)
- Local live runs copy the active config (with `agents.*.workspace` / `agentDir` overrides stripped) and each agent's `auth-profiles.json` - not the rest of that agent's directory, so `workspace/` and `sandboxes/` data never reaches the staged home - plus the legacy `credentials/` dir and supported external CLI auth files/dirs (`.claude.json`, `.claude/.credentials.json`, `.claude/settings*.json`, `.claude/backups`, `.codex/auth.json`, `.codex/config.toml`, `.gemini`, `.minimax`) into a temp test home.
If you want to rely on env keys, export them before local tests or use the
Docker runners below with an explicit `OPENCLAW_PROFILE_FILE`.
## Deepgram live (audio transcription)
- Test: `extensions/deepgram/audio.live.test.ts`
- Enable: `DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts`
## BytePlus coding plan live
- Test: `extensions/byteplus/live.test.ts`
- Enable: `BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts`
- Optional model override: `BYTEPLUS_CODING_MODEL=ark-code-latest`
## ComfyUI workflow media live
- Test: `extensions/comfy/comfy.live.test.ts`
- Enable: `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts`
- Scope:
- Exercises the bundled comfy image, video, and `music_generate` paths
- Skips each capability unless `plugins.entries.comfy.config.<capability>` is configured
- Useful after changing comfy workflow submission, polling, downloads, or plugin registration
## Image generation live
- Test: `test/image-generation.runtime.live.test.ts`
- Command: `pnpm test:live test/image-generation.runtime.live.test.ts`
- Harness: `pnpm test:live:media image`
- Scope:
- Enumerates every registered image-generation provider plugin
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs each configured provider through the shared image-generation runtime:
- `<provider>:generate`
- `<provider>:edit` when the provider declares edit support
- Current bundled providers covered:
- `deepinfra`
- `fal`
- `google`
- `minimax`
- `openai`
- `openrouter`
- `vydra`
- `xai`
- Optional narrowing:
- `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google,openrouter,xai"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="deepinfra"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,openrouter/google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,openrouter:generate,xai:default-generate,xai:default-edit"`
- Optional auth behavior:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` to force profile-store auth and ignore env-only overrides
For the shipped CLI path, add an `infer` smoke after the provider/runtime live
test passes:
```bash
OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_INFER_CLI_TEST=1 pnpm test:live -- test/image-generation.infer-cli.live.test.ts
openclaw infer image providers --json
openclaw infer image generate \
--model google/gemini-3.1-flash-image-preview \
--prompt "Minimal flat test image: one blue square on a white background, no text." \
--output ./openclaw-infer-image-smoke.png \
--json
```
This covers CLI argument parsing, config/default-agent resolution, bundled
plugin activation, the shared image-generation runtime, and the live provider
request. Plugin dependencies are expected to be present before runtime load.
## Music generation live
- Test: `extensions/music-generation-providers.live.test.ts`
- Enable: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media music`
- Scope:
- Exercises the shared bundled music-generation provider path
- Currently covers `fal`, `google`, `minimax`, and `openrouter`
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs both declared runtime modes when available:
- `generate` with prompt-only input
- `edit` when the provider declares `capabilities.edit.enabled`
- `comfy` has its own separate live file, not this shared sweep
- Optional narrowing:
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.6"`
- Optional auth behavior:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` to force profile-store auth and ignore env-only overrides
## Video generation live
- Test: `extensions/video-generation-providers.live.test.ts`
- Enable: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
- Harness: `pnpm test:live:media video`
- Scope:
- Exercises the shared bundled video-generation provider path across `alibaba`, `byteplus`, `deepinfra`, `fal`, `google`, `minimax`, `openai`, `openrouter`, `pixverse`, `qwen`, `runway`, `together`, `vydra`, `xai`
- Defaults to the release-safe smoke path: one text-to-video request per provider, one-second lobster prompt, and a per-provider operation cap from `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (`180000` by default)
- Skips FAL by default because provider-side queue latency can dominate release time; pass `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` (or clear the skip list) to run it explicitly
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs only `generate` by default
- Set `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` to also run declared transform modes when available:
- `imageToVideo` when the provider declares `capabilities.imageToVideo.enabled` and the selected provider/model accepts buffer-backed local image input in the shared sweep
- `videoToVideo` when the provider declares `capabilities.videoToVideo.enabled` and the selected provider/model accepts buffer-backed local video input in the shared sweep
- Current declared-but-skipped `imageToVideo` provider in the shared sweep:
- `vydra` (buffer-backed local image input is not supported in this lane)
- Provider-specific Vydra coverage:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts`
- That file runs `veo3` text-to-video plus a `kling` image-to-video lane that uses a remote image URL fixture by default (`OPENCLAW_LIVE_VYDRA_KLING_IMAGE_URL` to override).
- Current `videoToVideo` live coverage:
- `runway` only when the selected model resolves to `gen4_aleph`
- Current declared-but-skipped `videoToVideo` providers in the shared sweep:
- `alibaba`, `google`, `openai`, `qwen`, `xai` because those paths currently require remote `http(s)` reference URLs rather than buffer-backed local input
- Optional narrowing:
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="deepinfra,google,openai,runway"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` to include every provider in the default sweep, including FAL
- `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` to reduce each provider operation cap for an aggressive smoke run
- Optional auth behavior:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` to force profile-store auth and ignore env-only overrides
## Media live harness
- Command: `pnpm test:live:media`
- Entrypoint: `test/e2e/qa-lab/media/hosted-media-provider-live.ts`, which runs `pnpm test:live -- <suite-test-file>` per selected suite, so heartbeat and quiet-mode behavior stay consistent with other `pnpm test:live` runs.
- Purpose:
- Runs the shared image, music, and video live suites through one repo-native entrypoint
- Auto-loads missing provider env vars from `~/.profile`
- Auto-narrows each suite to providers that currently have usable auth by default
- Flags:
- `--providers <csv>` global provider filter; `--image-providers` / `--music-providers` / `--video-providers` scope a filter to one suite
- `--all-providers` skips the auth-based auto-filter
- `--allow-empty` exits `0` when filtering leaves no runnable providers
- `--quiet` / `--no-quiet` passed through to `test:live`
- Examples:
- `pnpm test:live:media`
- `pnpm test:live:media image video --providers openai,google,minimax`
- `pnpm test:live:media video --video-providers openai,runway --all-providers`
- `pnpm test:live:media music --quiet`
## Related
- [Testing](/help/testing) - unit, integration, QA, and Docker suites

View File

@@ -0,0 +1,303 @@
---
summary: "How OpenClaw validates update paths, package migrations, and plugin install/update behavior"
read_when:
- Changing OpenClaw update, doctor, package acceptance, or plugin install behavior
- Preparing or approving a release candidate
- Debugging package update, plugin dependency cleanup, or plugin install regressions
title: "Testing: updates and plugins"
sidebarTitle: "Update and plugin tests"
---
Checklist for update and plugin validation: prove the installable package can
update real user state, repair stale legacy state through `doctor`, and still
install, load, update, and uninstall plugins from every supported source.
For the broader test runner map, see [Testing](/help/testing). For live provider
keys and network-touching suites, see [Testing live](/help/testing-live).
## What we protect
- A package tarball is complete, has a valid `dist/postinstall-inventory.json`,
and does not depend on unpacked repo files.
- A user can move from an older published package to the candidate package
without losing config, agents, sessions, workspaces, plugin allowlists, or
channel config.
- `openclaw doctor --fix --non-interactive` owns legacy cleanup and repair
paths. Startup should not grow hidden compatibility migrations for stale
plugin state.
- Plugin installs work from local directories, git repos, npm packages, and the
ClawHub registry path.
- Plugin npm dependencies install in one managed npm project per plugin,
get scanned before trust, and get removed through `npm uninstall` during
plugin uninstall so hoisted dependencies do not linger.
- Plugin update is a no-op when nothing changed: install records, resolved
source, installed dependency layout, and enabled state stay intact.
## Local proof during development
Start narrow:
```bash
pnpm changed:lanes --json
pnpm check:changed
pnpm test:changed
```
For plugin install, uninstall, dependency, or package-inventory changes, also
run the focused tests that cover the edited seam:
```bash
pnpm test src/plugins/uninstall.test.ts src/infra/package-dist-inventory.test.ts test/scripts/package-acceptance-workflow.test.ts
```
Before any package Docker lane consumes a tarball, prove the package artifact:
```bash
pnpm release:check
```
`release:check` runs config/docs/API drift checks (config schema, config docs
baseline, plugin SDK API baseline and exports, plugin versions/inventory),
writes the package dist inventory, runs `npm pack --dry-run`, rejects forbidden
packed files, installs the tarball into a temp prefix, runs postinstall, and
smokes bundled channel entrypoints.
## Docker lanes
The Docker lanes are the product-level proof. They install or update a real
package inside Linux containers and assert behavior through CLI commands,
Gateway startup, HTTP probes, RPC status, and filesystem state.
Use focused lanes while iterating:
```bash
pnpm test:docker:plugins
pnpm test:docker:plugin-lifecycle-matrix
pnpm test:docker:plugin-update
pnpm test:docker:upgrade-survivor
pnpm test:docker:published-upgrade-survivor
pnpm test:docker:update-restart-auth
pnpm test:docker:update-migration
```
Important lanes:
- `test:docker:plugins` covers plugin install smoke, local folder installs,
local folder update skip behavior, local folders with preinstalled
dependencies, `file:` package installs, git installs with CLI execution, git
moving-ref updates, npm registry installs with hoisted transitive
dependencies, npm update no-ops, malformed npm package metadata rejection,
local ClawHub fixture installs and update no-ops, marketplace update behavior,
and Claude-bundle enable/inspect. Set `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` to
keep the ClawHub block hermetic/offline.
- `test:docker:plugin-lifecycle-matrix` installs the candidate package in a bare
container, runs an npm plugin through install, inspect, disable, enable,
explicit upgrade, explicit downgrade, and uninstall after deleting the plugin
code. It logs RSS and CPU metrics per phase.
- `test:docker:plugin-update` validates that an unchanged installed plugin does
not reinstall or lose install metadata during `openclaw plugins update`.
- `test:docker:upgrade-survivor` installs the candidate tarball over a dirty
old-user fixture, runs package update plus non-interactive doctor, then starts
a loopback Gateway and checks state preservation.
- `test:docker:published-upgrade-survivor` first installs a published baseline,
configures it through a baked `openclaw config set` recipe, updates it to the
candidate tarball, runs doctor, checks legacy cleanup, starts the Gateway, and
probes `/healthz`, `/readyz`, and RPC status.
- `test:docker:update-restart-auth` installs the candidate package, starts a
managed token-auth Gateway, unsets caller gateway auth env for
`openclaw update --yes --json`, and requires the candidate update command to
restart the Gateway before the normal probes.
- `test:docker:update-migration` is the cleanup-heavy published-update lane. It
starts from a configured Discord/Telegram-style user state, runs baseline
doctor so configured plugin dependencies have a chance to materialize, seeds
legacy plugin dependency debris for a configured packaged plugin, updates to
the candidate tarball, and requires post-update doctor to remove the legacy
dependency roots.
Useful published-upgrade survivor variants:
```bash
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC=openclaw@2026.4.23 \
OPENCLAW_UPGRADE_SURVIVOR_SCENARIO=versioned-runtime-deps \
pnpm test:docker:published-upgrade-survivor
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC=openclaw@latest \
OPENCLAW_UPGRADE_SURVIVOR_SCENARIO=bootstrap-persona \
pnpm test:docker:published-upgrade-survivor
```
Available scenarios: `base`, `acpx-openclaw-tools-bridge`, `feishu-channel`,
`bootstrap-persona`, `channel-post-core-restore`, `plugin-deps-cleanup`,
`configured-plugin-installs`, `stale-source-plugin-shadow`, `tilde-log-path`,
and `versioned-runtime-deps`. In aggregate runs, `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues`
(alias `far-reaching`) expands to all scenarios, including the
configured-plugin install migration.
Full update migration is intentionally separate from Full Release CI. Use the
manual `Update Migration` workflow when the release question is "can every
published stable release from 2026.4.23 onward update to this candidate and
clean up plugin dependency debris?":
```bash
gh workflow run update-migration.yml \
--ref main \
-f workflow_ref=main \
-f package_ref=main \
-f baselines=all-since-2026.4.23 \
-f scenarios=plugin-deps-cleanup
```
## Package Acceptance
Package Acceptance is the GitHub-native package gate. It resolves one candidate
package into a `package-under-test` tarball, records version and SHA-256, then
runs reusable Docker E2E lanes against that exact tarball. The workflow harness
ref is separate from the package source ref, so current test logic can validate
older trusted releases.
Candidate sources:
- `source=npm`: validate `openclaw@extended-stable`, `openclaw@beta`,
`openclaw@latest`, or an exact published version.
- `source=ref`: pack a trusted branch, tag, or commit with the selected current
harness.
- `source=url`: validate a public HTTPS tarball with required `package_sha256`.
This path rejects URL credentials, non-default HTTPS ports, private/internal
hostnames or DNS/IP results, special-use IP space, and unsafe redirects.
- `source=trusted-url`: validate an HTTPS tarball with required
`package_sha256` and `trusted_source_id` against the maintainer-owned policy
in `.github/package-trusted-sources.json`. Use this for enterprise/private
mirrors instead of weakening `source=url` with an input-level allow-private
switch. Bearer auth, when configured by policy, uses the fixed
`OPENCLAW_TRUSTED_PACKAGE_TOKEN` secret.
- `source=artifact`: reuse a tarball uploaded by another Actions run.
Full Release Validation uses `source=artifact` by default, built from the
resolved release SHA. For post-publish proof, pass
`package_acceptance_package_spec=openclaw@YYYY.M.PATCH` so the same upgrade matrix
targets the shipped npm package instead.
Release checks call Package Acceptance with the package/update/restart/plugin set:
```text
doctor-switch update-channel-switch skill-install update-corrupt-plugin upgrade-survivor published-upgrade-survivor root-managed-vps-upgrade update-restart-auth plugins-offline plugin-update plugin-binding-command-escape
```
When release soak is enabled (forced on for `release_profile=stable` and
`full`), they also pass:
```text
published_upgrade_survivor_baselines=last-stable-4 2026.4.23 2026.5.2 2026.4.15
published_upgrade_survivor_scenarios=reported-issues
telegram_mode=mock-openai
```
This keeps package migration, update channel switching, corrupt managed-plugin
tolerance, stale plugin dependency cleanup, offline plugin coverage, plugin
update behavior, and Telegram package QA on the same resolved artifact without
making the default release package gate walk every published release.
`last-stable-4` resolves to the four latest stable npm-published OpenClaw
releases. Release package acceptance pins `2026.4.23` as the first plugin-update
compatibility boundary, `2026.5.2` as a plugin-architecture churn boundary, and
`2026.4.15` as an older 2026.4.1x published-update baseline; the resolver
dedupes pins that are already in the latest four. For exhaustive published
update migration coverage, use `all-since-2026.4.23` in the separate Update
Migration workflow instead of Full Release CI. `release-history` remains
available for manual wider sampling when you also want the legacy pre-date
anchor.
When multiple published-upgrade survivor baselines are selected, the reusable
Docker workflow shards each baseline into its own targeted runner job. Each
baseline shard still runs the selected scenario set, but logs and artifacts stay
per-baseline and wall time is bounded by the slowest shard instead of one large
serial job.
Run a package profile manually when validating a candidate before release:
```bash
gh workflow run package-acceptance.yml \
--ref main \
-f workflow_ref=main \
-f source=npm \
-f package_spec=openclaw@beta \
-f suite_profile=package \
-f published_upgrade_survivor_baselines="last-stable-4 2026.4.23 2026.5.2 2026.4.15" \
-f published_upgrade_survivor_scenarios=reported-issues \
-f telegram_mode=mock-openai
```
For a published extended-stable canary, set
`package_spec=openclaw@extended-stable`. Package Acceptance resolves that
selector into an exact tarball before the Docker lanes run.
Use `suite_profile=product` when the release question includes MCP channels,
cron/subagent cleanup, OpenAI web search, or OpenWebUI. Use `suite_profile=full`
only when you need full Docker release-path coverage.
## Release default
For release candidates, the default proof stack is:
1. `pnpm check:changed` and `pnpm test:changed` for source-level regressions.
2. `pnpm release:check` for package artifact integrity.
3. Package Acceptance `package` profile or the release-check custom package
lanes for install/update/restart/plugin contracts.
4. Cross-OS release checks for OS-specific installer, onboarding, and platform
behavior.
5. Live suites only when the changed surface touches provider or hosted-service
behavior.
On maintainer machines, broad gates and Docker/package product proof should run
in Testbox unless explicitly doing local proof.
## Legacy compatibility
Compatibility leniency is narrow and time boxed:
- Packages through `2026.4.25`, including `2026.4.25-beta.*`, may tolerate
already-shipped package metadata gaps in Package Acceptance.
- The published `2026.4.26` package may warn for local build metadata stamp
files already shipped.
- Later packages must satisfy modern contracts. The same gaps fail instead of
warning or skipping.
Do not add new startup migrations for these old shapes. Add or extend a doctor
repair, then prove it with `upgrade-survivor`, `published-upgrade-survivor`, or
`update-restart-auth` when the update command owns the restart.
## Adding coverage
When changing update or plugin behavior, add coverage at the lowest layer that
can fail for the right reason:
- Pure path or metadata logic: unit test beside the source.
- Package inventory or packed-file behavior: `package-dist-inventory` or tarball
checker test.
- CLI install/update behavior: Docker lane assertion or fixture.
- Published-release migration behavior: `published-upgrade-survivor` scenario.
- Update-owned restart behavior: `update-restart-auth`.
- Registry/package source behavior: `test:docker:plugins` fixture or ClawHub
fixture server.
- Dependency layout or cleanup behavior: assert both runtime execution and the
filesystem boundary. npm dependencies may be hoisted inside the plugin's
managed npm project, so tests should prove that project is scanned/cleaned
instead of assuming only the plugin package-local `node_modules` tree.
Keep new Docker fixtures hermetic by default. Use local fixture registries and
fake packages unless the point of the test is live registry behavior.
## Failure triage
Start with the artifact identity:
- Package Acceptance `resolve_package` summary: source, version, SHA-256, and
artifact name.
- Docker artifacts: `.artifacts/docker-tests/**/summary.json`,
`failures.json`, lane logs, and rerun commands.
- Upgrade survivor summary: `.artifacts/upgrade-survivor/summary.json`,
including baseline version, candidate version, scenario, phase timings, and
config recipe coverage.
Prefer rerunning the failed exact lane with the same package artifact over
rerunning the whole release umbrella.

1105
docs/help/testing.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,452 @@
---
summary: "Symptom first troubleshooting hub for OpenClaw"
read_when:
- OpenClaw is not working and you need the fastest path to a fix
- You want a triage flow before diving into deep runbooks
title: "General troubleshooting"
---
Triage front door. 2 minutes to a diagnosis, then jump to the deep page.
## First 60 seconds
Run this ladder in order:
```bash
openclaw status
openclaw status --all
openclaw gateway probe
openclaw gateway status
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
```
Good output, one line each:
- `openclaw status` shows configured channels, no auth errors.
- `openclaw status --all` produces a full, shareable report.
- `openclaw gateway probe` shows `Reachable: yes`. `Capability: ...` is the
auth level the probe proved; `Read probe: limited - missing scope:
operator.read` is degraded diagnostics, not a connect failure.
- `openclaw gateway status` shows `Runtime: running`, `Connectivity probe:
ok`, and a plausible `Capability: ...`. Add `--require-rpc` to also require
read-scope RPC proof.
- `openclaw doctor` reports no blocking config/service errors.
- `openclaw channels status --probe` returns live per-account transport state
(`works` / `audit ok`) when the gateway is reachable; falls back to
config-only summaries when it is not.
- `openclaw logs --follow` shows steady activity, no repeating fatal errors.
## Assistant feels limited or missing tools
Check the effective tool profile:
```bash
openclaw status
openclaw status --all
openclaw doctor
```
Common causes:
- `tools.profile: "minimal"` allows only `session_status`.
- `tools.profile: "messaging"` is narrow, for chat-only agents.
- `tools.profile: "coding"` is the default for new local configs (repo, file,
shell, and runtime work).
- `tools.profile: "full"` removes profile restrictions; limit to trusted
operator-controlled agents.
- Per-agent `agents.list[].tools` overrides narrow or expand the root profile
for one agent.
Change the profile, restart or reload the Gateway, then recheck with
`openclaw status --all`. Full profile/group table: [Tool profiles](/gateway/config-tools#tool-profiles).
## Anthropic long context 429
`HTTP 429: rate_limit_error: Extra usage is required for long context requests`
→ [Anthropic 429 extra usage required for long context](/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context).
## Local OpenAI-compatible backend works directly but fails in OpenClaw
Your local/self-hosted `/v1` backend answers direct `/v1/chat/completions`
probes but fails on `openclaw infer model run` or normal agent turns:
1. Error mentions `messages[].content` expecting a string: set
`models.providers.<provider>.models[].compat.requiresStringContent: true`.
2. Still fails only on OpenClaw agent turns: set
`models.providers.<provider>.models[].compat.supportsTools: false` and retry.
3. Tiny direct calls work but larger OpenClaw prompts crash the backend: that
is an upstream model/server limit, not an OpenClaw bug. Continue in
[Local OpenAI-compatible backend passes direct probes but agent runs fail](/gateway/troubleshooting#local-openai-compatible-backend-passes-direct-probes-but-agent-runs-fail).
## Plugin install fails with missing openclaw extensions
`package.json missing openclaw.extensions` means the plugin package uses a
shape OpenClaw no longer accepts.
Fix in the plugin package:
1. Add `openclaw.extensions` to `package.json`, pointing at built runtime
files (usually `./dist/index.js`).
2. Republish, then run `openclaw plugins install <package>` again.
```json
{
"name": "@openclaw/my-plugin",
"version": "1.2.3",
"openclaw": {
"extensions": ["./dist/index.js"]
}
}
```
Reference: [Plugin architecture](/plugins/architecture)
## Install policy blocks plugin installs or updates
Update finishes but plugins are stale, disabled, or show `blocked by install
policy`, `install policy failed closed`, or `Disabled "<plugin>" after plugin
update failure`: check `security.installPolicy`.
Install policy runs on plugin installs and updates. `@openclaw/*` plugin
versions normally move with the OpenClaw release, so an OpenClaw update can
need a matching plugin update during post-update sync.
Avoid these policy shapes unless you also maintain the matching upgrade rule:
- Freezing OpenClaw-owned plugins to one exact old version (for example, only
`@openclaw/*@2026.5.3`).
- Blocking by source kind alone (every npm, network, or `request.mode:
"update"` request).
- Treating the policy command as optional: when `security.installPolicy` is
enabled, a missing, slow, unreadable, or permission-blocked policy
executable fails closed.
- Approving versions without checking the request's `openclawVersion` against
plugin candidate metadata.
Prefer rules that allow trusted `@openclaw/*` updates compatible with the
current host, instead of pinning one release forever. If you block npm by
default, add a narrow exception for the plugin ids you use, and apply the same
trust rule to `request.mode: "update"` as to installs.
Recovery:
```bash
openclaw doctor --deep
openclaw plugins update --all
openclaw status --all
```
If the policy is intentionally strict, relax it for the trusted upgrade
window, rerun `openclaw plugins update --all`, then restore the stricter rule.
If update failure disabled a plugin, inspect before re-enabling:
```bash
openclaw plugins inspect <plugin-id> --runtime --json
openclaw plugins enable <plugin-id>
```
Reference: [Operator install policy](/tools/skills-config#operator-install-policy-securityinstallpolicy)
## Plugin present but blocked by suspicious ownership
`openclaw doctor`, setup, or startup warnings show:
```text
blocked plugin candidate: suspicious ownership (... uid=1000, expected uid=0 or root)
plugin present but blocked
```
The plugin files are owned by a different Unix user than the process loading
them. Do not remove the plugin config; fix the file ownership, or run
OpenClaw as the user that owns the state directory.
Docker installs run as `node` (uid `1000`). Repair the host bind mounts:
```bash
sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace
openclaw doctor --fix
```
If you intentionally run OpenClaw as root, repair the managed plugin root
instead:
```bash
sudo chown -R root:root /path/to/openclaw-config/npm
openclaw doctor --fix
```
Deeper docs: [Blocked plugin path ownership](/tools/plugin#blocked-plugin-path-ownership), [Docker: Permissions and EACCES](/install/docker#shell-helpers-optional)
## Decision tree
```mermaid
flowchart TD
A[OpenClaw is not working] --> B{What breaks first}
B --> C[No replies]
B --> D[Dashboard or Control UI will not connect]
B --> E[Gateway will not start or service not running]
B --> F[Channel connects but messages do not flow]
B --> G[Cron or heartbeat did not fire or did not deliver]
B --> H[Node is paired but camera canvas screen exec fails]
B --> I[Browser tool fails]
C --> C1[/No replies section/]
D --> D1[/Control UI section/]
E --> E1[/Gateway section/]
F --> F1[/Channel flow section/]
G --> G1[/Automation section/]
H --> H1[/Node tools section/]
I --> I1[/Browser section/]
```
<AccordionGroup>
<Accordion title="No replies">
```bash
openclaw status
openclaw gateway status
openclaw channels status --probe
openclaw pairing list --channel <channel> [--account <id>]
openclaw logs --follow
```
Good output:
- `Runtime: running`
- `Connectivity probe: ok`
- `Capability: read-only`, `write-capable`, or `admin-capable`
- Channel shows transport connected and, where supported, `works` or
`audit ok` in `channels status --probe`
- Sender is approved (or DM policy is open/allowlist)
Log signatures:
- `drop guild message (mention required` → Discord mention gating blocked the message.
- `pairing request` → sender unapproved, waiting on DM pairing approval.
- `blocked` / `allowlist` in channel logs → sender, room, or group filtered.
Deep pages: [No replies](/gateway/troubleshooting#no-replies), [Channel troubleshooting](/channels/troubleshooting), [Pairing](/channels/pairing)
</Accordion>
<Accordion title="Dashboard or Control UI will not connect">
```bash
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
```
Good output:
- `Dashboard: http://...` shown in `openclaw gateway status`
- `Connectivity probe: ok`
- `Capability: read-only`, `write-capable`, or `admin-capable`
- No auth loop in logs
Log signatures:
- `device identity required` → HTTP/non-secure context cannot complete device auth.
- `origin not allowed` → browser `Origin` is not allowed for the Control UI gateway target.
- `AUTH_TOKEN_MISMATCH` with `canRetryWithDeviceToken=true` → one trusted device-token retry may occur automatically, reusing the paired token's cached scopes.
- repeated `unauthorized` after that retry → wrong token/password, auth mode mismatch, or stale paired device token.
- `too many failed authentication attempts (retry later)` → repeated failures from that browser `Origin` are temporarily locked out; other localhost origins use separate buckets. See [Dashboard/Control UI connectivity](/gateway/troubleshooting#dashboard-control-ui-connectivity) for the Tailscale Serve concurrent-retry nuance.
- `gateway connect failed:` → UI targets the wrong URL/port, or the gateway is unreachable.
Deep pages: [Dashboard/Control UI connectivity](/gateway/troubleshooting#dashboard-control-ui-connectivity), [Control UI](/web/control-ui), [Authentication](/gateway/authentication)
</Accordion>
<Accordion title="Gateway will not start or service installed but not running">
```bash
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
```
Good output:
- `Service: ... (loaded)`
- `Runtime: running`
- `Connectivity probe: ok`
- `Capability: read-only`, `write-capable`, or `admin-capable`
Log signatures:
- `Gateway start blocked: set gateway.mode=local` or `existing config is missing gateway.mode` → gateway mode is remote, or config is missing the local-mode stamp and needs repair.
- `refusing to bind gateway ... without auth` → non-loopback bind without a valid auth path (token/password, or trusted-proxy where configured).
- `another gateway instance is already listening` or `EADDRINUSE` → port already taken.
Deep pages: [Gateway service not running](/gateway/troubleshooting#gateway-service-not-running), [Background process](/gateway/background-process), [Configuration](/gateway/configuration)
</Accordion>
<Accordion title="Channel connects but messages do not flow">
```bash
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
```
Good output:
- Channel transport connected.
- Pairing/allowlist checks pass.
- Mentions detected where required.
Log signatures:
- `mention required` → group mention gating blocked processing.
- `pairing` / `pending` → DM sender not approved yet.
- `not_in_channel`, `missing_scope`, `Forbidden`, `401/403` → channel permission token issue.
Deep pages: [Channel connected, messages not flowing](/gateway/troubleshooting#channel-connected-messages-not-flowing), [Channel troubleshooting](/channels/troubleshooting)
</Accordion>
<Accordion title="Cron or heartbeat did not fire or did not deliver">
```bash
openclaw status
openclaw gateway status
openclaw cron status
openclaw cron list
openclaw cron runs --id <jobId> --limit 20
openclaw logs --follow
```
Good output:
- `cron status` shows the scheduler enabled with a next wake.
- `cron runs` shows recent `ok` entries.
- Heartbeat is enabled and inside active hours.
Log signatures:
- `cron: scheduler disabled; jobs will not run automatically` → cron is disabled.
- `heartbeat skipped` reason `quiet-hours` → outside configured active hours.
- `heartbeat skipped` reason `empty-heartbeat-file` → `HEARTBEAT.md` exists but contains only blank, comment, header, fence, or empty-checklist scaffolding.
- `heartbeat skipped` reason `no-tasks-due` → task mode is active but no task interval is due yet.
- `heartbeat skipped` reason `alerts-disabled` → `showOk`, `showAlerts`, and `useIndicator` are all off.
- `requests-in-flight` → main lane busy; heartbeat wake deferred.
- `unknown accountId` → heartbeat delivery target account does not exist.
Deep pages: [Cron and heartbeat delivery](/gateway/troubleshooting#cron-and-heartbeat-delivery), [Scheduled tasks: Troubleshooting](/automation/cron-jobs#troubleshooting), [Heartbeat](/gateway/heartbeat)
</Accordion>
<Accordion title="Node is paired but tool fails camera canvas screen exec">
```bash
openclaw status
openclaw gateway status
openclaw nodes status
openclaw nodes describe --node <idOrNameOrIp>
openclaw logs --follow
```
Good output:
- Node listed as connected and paired for role `node`.
- Capability exists for the command you are invoking.
- Permission state granted for the tool.
Log signatures:
- `NODE_BACKGROUND_UNAVAILABLE` → bring the node app to the foreground.
- `*_PERMISSION_REQUIRED` → OS permission denied/missing.
- `SYSTEM_RUN_DENIED: approval required` → exec approval is pending.
- `SYSTEM_RUN_DENIED: allowlist miss` → command not on the exec allowlist.
Deep pages: [Node paired, tool fails](/gateway/troubleshooting#node-paired-tool-fails), [Node troubleshooting](/nodes/troubleshooting), [Exec approvals](/tools/exec-approvals)
</Accordion>
<Accordion title="Exec suddenly asks for approval">
```bash
openclaw config get tools.exec.host
openclaw config get tools.exec.security
openclaw config get tools.exec.ask
openclaw gateway restart
```
What changed:
- Unset `tools.exec.host` defaults to `auto`, which resolves to `sandbox`
when a sandbox runtime is active, `gateway` otherwise.
- `host=auto` only routes; the no-prompt behavior comes from
`security=full` plus `ask=off` on gateway/node.
- Unset `tools.exec.security` defaults to `full` on `gateway`/`node`.
- Unset `tools.exec.ask` defaults to `off`.
- If you are seeing approvals, some host-local or per-session policy
tightened exec away from these defaults.
Restore the current no-approval defaults:
```bash
openclaw config set tools.exec.host gateway
openclaw config set tools.exec.security full
openclaw config set tools.exec.ask off
openclaw gateway restart
```
Safer alternatives:
- Set only `tools.exec.host=gateway` for stable host routing.
- Use `security=allowlist` with `ask=on-miss` for host exec with review on
allowlist misses.
- Enable sandbox mode so `host=auto` resolves back to `sandbox`.
Log signatures:
- `Approval required.` → command is waiting on `/approve ...`.
- `SYSTEM_RUN_DENIED: approval required` → node-host exec approval is pending.
- `exec host=sandbox requires a sandbox runtime for this session` → implicit/explicit sandbox selection but sandbox mode is off.
Deep pages: [Exec](/tools/exec), [Exec approvals](/tools/exec-approvals), [Security: What the audit checks](/gateway/security#what-the-audit-checks-high-level)
</Accordion>
<Accordion title="Browser tool fails">
```bash
openclaw status
openclaw gateway status
openclaw browser status
openclaw logs --follow
openclaw doctor
```
Good output:
- Browser status shows `running: true` and a chosen browser/profile.
- `openclaw` profile starts, or `user` profile sees local Chrome tabs.
Log signatures:
- `unknown command "browser"` → `plugins.allow` is set and excludes `browser`.
- `Failed to start Chrome CDP on port` → local browser launch failed.
- `browser.executablePath not found` → configured binary path is wrong.
- `browser.cdpUrl must be http(s) or ws(s)` → configured CDP URL uses an unsupported scheme.
- `browser.cdpUrl has invalid port` → configured CDP URL has a bad or out-of-range port.
- `No Chrome tabs found for profile="user"` → the Chrome MCP attach profile has no open local Chrome tabs.
- `Remote CDP for profile "<name>" is not reachable` → configured remote CDP endpoint unreachable from this host.
- `Browser attachOnly is enabled ... not reachable` → attach-only profile has no live CDP target.
- Stale viewport/dark-mode/locale/offline overrides on attach-only or remote CDP profiles → run `openclaw browser stop --browser-profile <name>` to close the control session and release emulation state without restarting the gateway.
Deep pages: [Browser tool fails](/gateway/troubleshooting#browser-tool-fails), [Missing browser command or tool](/tools/browser#missing-browser-command-or-tool), [Browser: Linux troubleshooting](/tools/browser-linux-troubleshooting), [Browser: WSL2/Windows remote CDP troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
</Accordion>
</AccordionGroup>
## Related
- [FAQ](/help/faq) — frequently asked questions
- [Gateway Troubleshooting](/gateway/troubleshooting) — gateway-specific issues
- [Doctor](/gateway/doctor) — automated health checks and repairs
- [Channel Troubleshooting](/channels/troubleshooting) — channel connectivity issues
- [Scheduled tasks: Troubleshooting](/automation/cron-jobs#troubleshooting) — cron and heartbeat issues