| name | openclaw-config-editor |
| description | Authoritative guide for editing openclaw.json configuration without hallucinating keys or values. Use this skill whenever you need to add, change, or remove any setting in openclaw.json, configure channels (including Zalo, ZaloUser, Feishu, LINE, Matrix, Nostr, Tlon, Twitch, Nextcloud Talk, Synology Chat, voice-call), models, agents, tools, sessions, or any other OpenClaw config section. Also use when the user says "configure", "set up", "config set", "edit config", "change setting", or references any openclaw.json path. This skill prevents invalid config that would cause the gateway to refuse to start. |
OpenClaw Config Editor
OpenClaw uses strict Zod validation on ~/.openclaw/openclaw.json (JSON5 format). Unknown keys, wrong types, or invalid values cause the gateway to refuse to start. This skill ensures you only use valid, documented config paths and values.
Golden Rules
- Never guess config keys. If a key is not in the section index below or the reference files, stop and look it up.
- Always dry-run first. Run
openclaw config set --dry-run <path> <value> before the real write.
- Always validate after. Run
openclaw config validate after any edit.
- Use the CLI, not direct file edits.
openclaw config set/unset has built-in schema validation.
- Read before you write. Use
openclaw config get <path> to see current values before changing them.
Workflow
1. User describes what they want to configure
2. Look up the section in the index below
3. If you need detailed field info, read the appropriate reference file:
- Core config: references/core-config.md
- Extension channels: references/channel-extensions.md
4. Compose: openclaw config set --dry-run <path> <value>
5. If dry-run passes -> run without --dry-run
If dry-run fails -> read the error, fix path/value, retry
6. Run: openclaw config validate
7. Restart gateway if needed (gateway.* changes require restart)
CLI Patterns
Get a value
openclaw config get agents.defaults.workspace
openclaw config get channels.telegram.botToken
Set a value
openclaw config set agents.defaults.workspace "~/my-workspace"
openclaw config set gateway.port 19001 --strict-json
openclaw config set channels.whatsapp.allowFrom '["*"]' --strict-json
openclaw config set agents.defaults.heartbeat '{"every":"2h"}' --strict-json
Set a secret reference (for tokens/API keys)
openclaw config set channels.discord.token \
--ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
Batch set (multiple values at once)
openclaw config set --batch-json '[
{"path": "channels.telegram.botToken", "ref": {"source": "env", "provider": "default", "id": "TELEGRAM_BOT_TOKEN"}},
{"path": "channels.telegram.dmPolicy", "value": "pairing"}
]'
Unset a value
openclaw config unset plugins.entries.brave.config.webSearch.apiKey
Validate
openclaw config validate
openclaw config validate --json
Known Pitfalls
Config Section Index
All config paths are listed below. For detailed field-level info, read the reference files.
Core channels (channels.*)
| Config path | Key fields |
|---|
channels.defaults | groupPolicy, heartbeat.showOk, heartbeat.showAlerts, heartbeat.useIndicator |
channels.modelByChannel | <channel>.<channelId> = "provider/model" |
channels.whatsapp | dmPolicy, allowFrom[], textChunkLimit, chunkMode, mediaMaxMb, sendReadReceipts, groups, groupPolicy, accounts |
channels.telegram | botToken, dmPolicy, allowFrom[], groups, topicMode, editSync, requireMention |
channels.discord | token, dmPolicy, allowFrom[], guilds, requireMention, threadBindings, reactions |
channels.slack | botToken, appToken, signingSecret, dmPolicy, channels, socketMode |
channels.signal | number, dmPolicy, allowFrom[], groups |
channels.imessage | dmPolicy, allowFrom[], applescriptFallback |
Extension channels (channels.*)
Read references/channel-extensions.md for detailed field-level schemas.
| Config path | Key fields |
|---|
channels.zalo | botToken(SecretRef), tokenFile, webhookUrl, webhookSecret, webhookPath, dmPolicy, allowFrom[], groupPolicy, groupAllowFrom[], mediaMaxMb, proxy |
channels.zalouser | profile, dangerouslyAllowNameMatching, dmPolicy, allowFrom[], historyLimit, groupPolicy(default:"allowlist"), groupAllowFrom[], groups, messagePrefix, responsePrefix |
channels.feishu | appId, appSecret(SecretRef), encryptKey(SecretRef), verificationToken(SecretRef), domain("feishu"|"lark"), connectionMode("websocket"|"webhook"), dmPolicy, groupPolicy, requireMention, groups, streaming, tools, accounts |
channels.line | channelAccessToken, channelSecret, tokenFile, secretFile, dmPolicy(default:"pairing"), groupPolicy(default:"allowlist"), groups, accounts |
channels.matrix | homeserver, userId, accessToken, password(SecretRef), deviceId, encryption, allowlistOnly, groupPolicy, rooms, autoJoin, threadBindings, actions |
channels.msteams | appId, appPassword(SecretRef), tenantId, webhook, dmPolicy(default:"pairing"), groupPolicy(default:"allowlist"), requireMention, teams |
channels.googlechat | serviceAccount(sensitive), serviceAccountFile, dmPolicy, groupPolicy(default:"allowlist"), requireMention, groups, webhookPath, streamMode |
channels.mattermost | botToken(SecretRef), baseUrl, dmPolicy(default:"pairing"), groupPolicy(default:"allowlist"), requireMention, commands |
channels.bluebubbles | serverUrl, password(SecretRef), dmPolicy, groupPolicy, groups, sendReadReceipts, actions |
channels.irc | host, port, tls, nick, username, password, passwordFile, nickserv, dmPolicy(default:"pairing"), groupPolicy(default:"allowlist"), channels |
channels.nostr | privateKey, relays[], dmPolicy, allowFrom[](npub/hex), profile |
channels.twitch | username(required), accessToken(required), channel(required), clientId, allowFrom[], allowedRoles[], requireMention, accounts |
channels.tlon | ship, url, code, groupChannels[], dmAllowlist[], autoDiscoverChannels, ownerShip, authorization, accounts |
channels.nextcloud-talk | baseUrl, botSecret(SecretRef), apiUser, apiPassword(SecretRef), dmPolicy(default:"pairing"), groupPolicy(default:"allowlist"), webhookPort, rooms, accounts |
channels.synology-chat | Passthrough schema (freeform fields accepted) |
Plugin config (not under channels.*)
| Config path | Key fields |
|---|
plugins.entries.voice-call.config | enabled, provider("telnyx"|"twilio"|"plivo"), fromNumber(E.164), inboundPolicy, allowFrom[], maxDurationSeconds, serve, tunnel, streaming, tts, stt |
Shared DM/group policies (all channels)
All channels support these standard policy fields:
| Field | Values | Default |
|---|
dmPolicy | "pairing" | "allowlist" | "open" | "disabled" | "pairing" |
groupPolicy | "allowlist" | "open" | "disabled" | "allowlist" |
allowFrom | string[] — sender IDs; ["*"] required for "open" | [] |
groupAllowFrom | string[] — group IDs | [] |
Core config sections
| Config path | Key fields |
|---|
agents.defaults.workspace | string path |
agents.defaults.model | primary, fallback[], thinkingBudget, temperature |
agents.defaults.heartbeat | every, channels, report, showOk |
agents.defaults.compaction | maxTokens, targetTokens, preserve |
agents.defaults.sandbox | enabled, image, volumes, env, network, caps |
agents.list | Per-agent overrides (array) |
bindings | Multi-agent routing rules |
session | scope, dmScope, identityLinks, reset, resetByType, maintenance, threadBindings, sendPolicy |
messages | responsePrefix, ackReaction, inboundDebounce, tts, queue |
talk | ElevenLabs/OpenAI voice config, voice aliases |
tools | profiles, allow[], deny[], elevated, exec, loopDetection, web, media, subagents, agentToAgent, sessions |
models | mode("merge"|"replace"), providers.* |
models.providers.* | baseUrl, apiKey, api("openai-completions"|"anthropic-messages"|"google-generative-ai"), auth, models[], headers |
skills | allowBundled[], load.extraDirs[], load.watch, install.preferBrew, install.nodeManager, entries.* |
plugins | enabled, allow[], deny[], entries.* |
browser | executablePath, cdp, profiles, snapshotDefaults, ssrfPolicy |
ui | seamColor, assistant.name, assistant.avatar |
gateway | port, bind, auth, tls, reload, remote, push, nodes, tailscale, healthMonitoring |
hooks | Webhook endpoints, mappings, Gmail integration |
canvasHost | Canvas host config |
discovery | mdns, wideArea |
env | shellEnv, vars, inline env vars |
secrets | SecretRef config, providers (env, file, exec) |
auth | Auth profiles, order, cooldowns |
logging | level, file, console, redaction |
cron | Cron jobs, retry, sessionRetention, runLog, failureAlerts |
media | preserveFilenames, ttlHours |
$include | Config includes for splitting config across files |
commands | Chat command handling: native, bash, config, debug, restart, allowFrom |
Common Config Recipes
Connect a channel
openclaw config set channels.telegram.botToken --ref-provider default --ref-source env --ref-id TELEGRAM_BOT_TOKEN
openclaw config set channels.telegram.dmPolicy "pairing"
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
openclaw config set channels.whatsapp.dmPolicy "allowlist"
openclaw config set channels.whatsapp.allowFrom '["+15555550123"]' --strict-json
openclaw config set channels.zalo.botToken --ref-provider default --ref-source env --ref-id ZALO_OA_TOKEN
openclaw config set channels.zalo.webhookUrl "https://example.com/zalo/webhook"
openclaw config set channels.zalo.dmPolicy "pairing"
openclaw config set channels.zalouser.dmPolicy "allowlist"
openclaw config set channels.zalouser.groupPolicy "allowlist"
openclaw config set channels.feishu.appId "cli_xxx"
openclaw config set channels.feishu.appSecret --ref-provider default --ref-source env --ref-id FEISHU_APP_SECRET
openclaw config set channels.feishu.connectionMode "websocket"
openclaw config set channels.feishu.dmPolicy "pairing"
openclaw config set channels.line.channelAccessToken --ref-provider default --ref-source env --ref-id LINE_CHANNEL_ACCESS_TOKEN
openclaw config set channels.line.channelSecret --ref-provider default --ref-source env --ref-id LINE_CHANNEL_SECRET
openclaw config set channels.matrix.homeserver "https://matrix.example.com"
openclaw config set channels.matrix.userId "@bot:example.com"
openclaw config set channels.matrix.accessToken --ref-provider default --ref-source env --ref-id MATRIX_ACCESS_TOKEN
Set the AI model
openclaw config set agents.defaults.model.primary "anthropic/claude-sonnet-4-6"
openclaw config set agents.defaults.model.fallback '["openai/gpt-4.1", "anthropic/claude-haiku-4-5"]' --strict-json
Add a custom model provider
openclaw config set models.providers.my-ollama \
'{"baseUrl":"http://localhost:11434/v1","api":"openai-completions","models":[{"id":"deepseek-coder","name":"DeepSeek Coder","reasoning":false,"input":["text"],"contextWindow":128000,"maxTokens":32000}]}' \
--strict-json
Configure session reset
openclaw config set session.reset '{"mode":"daily","atHour":4}' --strict-json
Configure heartbeat
openclaw config set agents.defaults.heartbeat.every "2h"
Set workspace
openclaw config set agents.defaults.workspace "~/my-workspace"
Voice call plugin
openclaw config set plugins.entries.voice-call.config \
'{"enabled":true,"provider":"twilio","fromNumber":"+15551234567","inboundPolicy":"pairing"}' \
--strict-json