Config writes
Plugins can read the running configuration and — when justified — writeopenclaw.json through the same guarded writer the CLI uses. Before reaching for a global config write, check whether your own plugin config (api.pluginConfig, declared in your manifest) covers the need: it is scoped, validated, and never risks clobbering unrelated settings.
The contract
Config access on the plugin API:register may be synchronous or async ((api: OpenClawPluginApi) => void | Promise<void>).
Prefer pluginConfig over global writes
If the values your plugin needs are yours alone, declare them inopenclaw.plugin.json and read them from api.pluginConfig. The manifest schema is plain JSON Schema:
plugins.entries.my-plugin.config in openclaw.json, the control UI renders a form from your schema, and you never touch the global document. Capture the value in a closure at registration time — do not read api.pluginConfig from inside execute():
Writing global config
When a plugin genuinely must change global config (for example a channel onboarding flow), useapi.runtime.config.writeConfigFile. It has the same guarantees as every other config write in the system:
- Validation first. The document is validated against the full schema including plugin schemas. An invalid config throws before anything touches disk.
- Top-level removal guard. If the write would drop a top-level key that exists on disk, it throws an error with
code === "CONFIG_WRITE_REFUSED". Name intended removals inoptions.allowTopLevelKeyRemoval. - Atomic write with backups. Temp file plus rename;
openclaw.json.bakplus a rotation ring of four more backups. ${VAR}restoration. Unchanged environment-variable references in the existing file are preserved, not replaced with resolved values.
What not to do
Do not construct the next document from a stale snapshot ofapi.config and write it back wholesale:
baseHash optimistic-concurrency check at this layer (that lives in the gateway RPC methods) — a plugin write is last-writer-wins at the file level, so keep the read-modify-write window short.
Restart and reload implications
A config write from a plugin lands on disk; the gateway file watcher then applies the reload policy:- Changes under your plugin’s own registration (installing or removing plugins,
plugins.*) require a gateway restart to take effect. - Many operational paths (
tools,agents,messages,cron,hooks,models) hot-reload or apply on the next turn under the defaultgateway.reload.mode: "hybrid". - If your plugin changes config at registration time, log a clear warning that a restart may be needed — the plugin runtime does not restart the gateway for you.
Async safety
writeConfigFile is async and performs file I/O with atomic rename — always await it, and never block the event loop around it:
register() stalls the event loop for the whole gateway process during startup.
Related
- Agent tools — registering tools that read
pluginConfig - Plugin manifest — declaring
configSchema - Config writes (admins) — the full write-path reference
- Reference: config