OpenClaw Config Patch: Change Agent Settings Without Guesswork
Read from search, close with the playbook
If this post helped, here is the fastest path into the full operator setup.
Search posts do the first job. The preview, homepage, and full playbook show how the pieces fit together when you want the whole operating system.
Config changes are where a lot of agent operations go from calm to expensive. One line points a workspace at the wrong directory. A channel token gets pasted into a file and later copied into a commit. A model setting is changed live, but nobody checks whether the Gateway accepted it. The agent keeps running until the next restart, and then the whole box refuses to boot.
OpenClaw gives operators enough tooling to avoid that mess. The habit is simple: know the active config file, make the smallest possible change, dry-run it when the CLI supports dry-run, validate the final shape, and understand whether the Gateway can hot-apply it or needs a restart. That is the difference between a patch and a guess.
The docs are clear about the baseline. OpenClaw reads an optional JSON5 config from ~/.openclaw/openclaw.json. If the file is missing, OpenClaw uses safe defaults. You add config when you need to connect channels, control who can message the bot, set models, tune tools, configure sandboxing, run automation, or change networking and UI behavior.
Start by proving which file you are touching
The first mistake is editing the config you think is active. Do not do that. Use openclaw config file before any real change. It prints the active config path, resolved from OPENCLAW_CONFIG_PATH or the default location. Then use openclaw config get against the exact path you care about.
openclaw config file
openclaw config get agents.defaults.workspace
openclaw config get channels.slack.dmPolicy
openclaw config validate --json Config paths use dot or bracket notation. The CLI docs show examples such as agents.defaults.workspace, agents.list[0].id, and agents.list[1].tools.exec.node. That matters for multi-agent boxes, because “change the agent config” is not precise enough when more than one agent has overrides.
I like to pair the target check with openclaw config validate --json. Validation checks the current config against the active schema without starting the Gateway. It is cheap evidence that you are not beginning from a broken file.
Use config set for small edits, not hand surgery
For single-key edits, openclaw config set is the boring safe path. Values are parsed as JSON5 when possible, or treated as strings. If you want to require JSON5 parsing, pass --strict-json. The legacy --json alias still works, but I would use the newer name in fresh runbooks.
The CLI supports four assignment styles: direct value mode, SecretRef builder mode, provider builder mode for secrets.providers.<alias>, and batch mode through --batch-json or --batch-file. That covers most operator changes without opening the raw file.
openclaw config set agents.defaults.heartbeat.every "2h" --dry-run --json
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN --dry-run --json The important flag is --dry-run. For builder mode, dry-run checks changed refs or providers for resolvability. For JSON and batch modes, dry-run also runs schema validation. With --dry-run --json, the CLI returns a machine-readable report with fields such as ok, operations, configPath, checks, refsChecked, skippedExecRefs, and structured errors.
There is one sharp edge worth saying out loud. Exec-backed SecretRefs are skipped by default during dry-run so a validation check does not silently execute provider commands. If you intentionally want exec SecretRef checks, add --allow-exec with --dry-run. The docs make --allow-exec dry-run only; it errors if used without dry-run in this config command path.
Batch related edits so they succeed or fail together
Some changes are only safe as a pair. A credential ref is useless if the provider does not exist. A channel update can be confusing if half the fields land and the other half fails validation. Batch mode keeps that intent visible.
openclaw config set --batch-json '[
{
"path": "secrets.providers.default",
"provider": { "source": "env" }
},
{
"path": "channels.discord.token",
"ref": { "source": "env", "provider": "default", "id": "DISCORD_BOT_TOKEN" }
}
]' --dry-run Batch parsing uses the batch payload as the source of truth. --strict-json and --json do not change batch parsing behavior. That is good for automation because the command shape stays predictable: prepare the operations, dry-run them, inspect the report, then write only after the dry-run is clean.
If dry-run fails, the docs divide failures into schema problems and SecretRef resolvability problems. Schema failures mean your post-change config shape is invalid. Resolvability failures mean the referenced provider or credential cannot resolve now, for example a missing environment variable, invalid file pointer, exec provider failure, or provider/source mismatch.
If you want the full operator workflow, config patches, SecretRefs, model routing, memory, cron discipline, and recovery checks in one place, get ClawKit here.
Use config.patch when you need a partial RPC update
The configuration docs also describe Gateway control-plane writes. config.apply validates and writes a full replacement config. That is powerful, but it is the wrong default for routine operator edits because it replaces the entire config. For partial updates, use config.patch.
config.patch merges a partial JSON5 payload into the existing config using JSON merge patch semantics. Objects merge recursively. null deletes a key. Arrays replace. The call requires a baseHash from config.get, which protects you from patching a stale view of the file.
openclaw gateway call config.get --params '{}'
openclaw gateway call config.patch --params '{
"raw": "{ channels: { telegram: { groups: { "*": { requireMention: false } } } } }",
"baseHash": "<hash-from-config.get>"
}' The RPC path has its own operational guardrail: control-plane write RPCs such as config.apply, config.patch, and update.run are rate-limited to three requests per sixty seconds per deviceId+clientIp. When limited, the RPC returns UNAVAILABLE with retryAfterMs. That is a good reason to avoid chatty automation loops that patch one tiny field at a time.
Know what reloads safely
OpenClaw watches ~/.openclaw/openclaw.json and applies changes automatically for most settings. The default reload mode is hybrid: safe changes hot-apply immediately, and restart-required changes are handled automatically. Other modes are hot, restart, and off.
{
gateway: {
reload: { mode: "hybrid", debounceMs: 300 },
},
} The docs group hot-applied categories broadly: channels and WhatsApp web settings, agents and models, hooks, cron, heartbeat, sessions, messages, tools, browser, skills, audio, talk, UI, logging, identity, and bindings. Gateway server settings such as port, bind, auth, Tailscale, TLS, and HTTP require restart. Infrastructure settings such as discovery, canvas host, and plugins also require restart. gateway.reload and gateway.remote are exceptions that do not trigger a restart.
That does not mean “never restart.” It means you should know what kind of change you are making before you make it. If the change affects the server boundary or infrastructure loading, plan for the restart instead of being surprised by it.
Respect strict validation
OpenClaw config is intentionally strict. Unknown keys, malformed types, or invalid values cause the Gateway to refuse to start. The only root-level exception documented is $schema, so editors can attach JSON Schema metadata.
When validation fails, the docs say the Gateway does not boot and only diagnostic commands work: openclaw doctor, openclaw logs, openclaw health, and openclaw status. The recovery path is not to keep editing blindly. Run openclaw doctor to see exact issues, then use openclaw doctor --fix or --yes when you want OpenClaw to apply supported repairs.
Do not smuggle secrets into config patches
A safe config patch should not be a fancy way to paste credentials into JSON. The SecretRef docs define one object shape: { source: "env" | "file" | "exec", provider: "default", id: "..." }. Env ids must follow the uppercase environment-variable pattern. File refs use absolute JSON pointers. Exec ids have their own restricted pattern and cannot contain . or .. slash-delimited path segments.
The supported credential surface is specific. It includes model provider API keys and headers, skill API keys, memory search keys, talk and TTS keys, web search keys, gateway auth token/password fields, cron webhook token, many channel bot tokens and secrets, and auth-profile key/token refs. It intentionally excludes runtime-minted or rotating material such as OAuth refresh material, session artifacts, some hook tokens, and WhatsApp credential files.
If you are doing a credentials migration, pair this post with the deeper OpenClaw SecretRefs guide. The short version is enough for config patches: references belong in config; values belong in env, file, or exec providers; unsupported credentials should not be forced into SecretRef shape just because it looks tidy.
Use includes for organization, not confusion
Large configs can be split with $include. A single included file replaces the containing object. An array of files deep-merges in order, with later files winning. Sibling keys merge after includes, so they override included values. Nested includes are supported up to ten levels deep, and relative paths resolve relative to the including file.
// ~/.openclaw/openclaw.json
{
gateway: { port: 18789 },
agents: { $include: "./agents.json5" },
broadcast: {
$include: ["./clients/a.json5", "./clients/b.json5"],
},
} The reference adds an important boundary: include paths must stay inside the top-level config directory, the directory containing openclaw.json. Absolute and ../ forms are allowed only when they still resolve inside that boundary. That keeps config organization from becoming arbitrary filesystem reach.
The patch checklist I would actually use
- Run
openclaw config fileand confirm the active target. - Read the current value with
openclaw config get. - Use
config set --dry-run --jsonor aconfig.patchpayload with a freshbaseHash. - For related changes, use batch mode or one partial patch, not a stream of tiny writes.
- Use SecretRefs for supported credentials and avoid plaintext secrets in config diffs.
- Run
openclaw config validate --jsonafter the write. - Know whether the change hot-applies or requires a restart under your reload mode.
Configuration is not glamorous, but it is where production agents become stable. A good OpenClaw operator does not trust memory, screenshots, or “I think this is the right file.” They trust the active path, the schema, a dry-run report, a base hash, and a verified reload path.
Want the complete guide? Get ClawKit — $9.99