Configuration System
OpenClaw's configuration system supports layered configuration, file watching, and hot-reload strategies, allowing the Gateway to apply most configuration changes without a restart.
Configuration Loading
Source: src/config/config.ts
Configuration is loaded from ~/.openclaw/openclaw.json, validated, normalized, and made available to all modules:
// src/config/config.ts (simplified)
function loadConfig(): OpenClawConfig {
// 1. Read ~/.openclaw/openclaw.json
// 2. Validate schema via Zod
// 3. Apply defaults
// 4. Normalize values
}Configuration File Structure
{
"gateway": {
"port": 18789,
"auth": { "mode": "token", "token": "..." }
},
"models": {
"default": "claude-sonnet-4-5-20250929",
"profiles": { /* ... */ }
},
"channels": {
"telegram": { "token": "...", "allowFrom": [...] },
"discord": { "token": "...", "guildId": "..." },
"whatsapp": { /* ... */ }
},
"plugins": { /* ... */ },
"hooks": { /* ... */ },
"cron": { /* ... */ }
}Hot-Reload Mechanism
Source: src/gateway/config-reload.ts
The Gateway uses chokidar to watch for configuration file changes and applies predefined rules to determine how to handle them:
Reload Plan
// src/gateway/config-reload.ts (simplified)
interface GatewayReloadPlan {
restartGateway: boolean; // Need full restart?
hotReasons: string[]; // Hot-reloadable changes
noopPaths: string[]; // Ignored changes
}
function getGatewayReloadPlan(
changedPaths: string[]
): GatewayReloadPlan {
// Analyze each changed file against reload rules
}Reload Rules
Each configuration path maps to a reload rule:
| Config Category | Reload Type | Description |
|---|---|---|
| Plugin config | restart | Plugin registry needs to be reloaded |
| Gateway core config | restart | Core parameter changes (port, auth) |
| Hooks config | hot | Re-register hooks at runtime |
| Cron config | hot | Reschedule cron jobs at runtime |
| Browser config | hot | Reinitialize browser profiles |
| Channel config | hot | Reload on a per-channel basis |
| Identity config | none | Takes effect on next session |
| Wizard config | none | Only used during initialization |
| Logging config | none | Requires manual restart |
| Model config | none | Takes effect at session level |
Channel-Specific Reload Rules
Different channels have different reload requirements:
// src/gateway/config-reload.ts (simplified)
// Channel-specific reload rules
const channelReloadRules = {
telegram: "hot", // Can hot-reload (reconnect bot)
whatsapp: "restart", // Needs full restart (Baileys session)
discord: "hot", // Can hot-reload (reconnect client)
slack: "hot", // Can hot-reload
signal: "restart", // Needs restart (signal-cli process)
};Debounce Mechanism
// src/gateway/config-reload.ts (simplified)
// Debounce 300ms to batch rapid changes
const RELOAD_DEBOUNCE_MS = 300;When a user edits the configuration file rapidly (e.g., saving multiple times), the debounce mechanism batches all changes within 300ms into a single reload operation.
Runtime Configuration
Source: src/gateway/server-runtime-config.ts
In addition to file-based configuration, the Gateway maintains runtime configuration state:
// src/gateway/server-runtime-config.ts (simplified)
interface RuntimeConfig {
// Dynamic configuration that can be patched at runtime
// Without writing to disk
}Runtime configuration is modified through the config.patch WebSocket method. Changes take effect immediately but are not persisted to disk.
Configuration Validation
Configuration is validated using Zod schemas to ensure type safety:
// Configuration validation
// Each section has its own Zod schema
// Invalid configs are rejected with descriptive error messagesReload Handlers
Source: src/gateway/server-reload-handlers.ts
Hot-reload is handled by dedicated reload handlers:
// src/gateway/server-reload-handlers.ts (simplified)
// Each hot-reloadable section has a handler:
// - reloadHooks(): Re-register all hooks
// - reloadCron(): Re-schedule all cron jobs
// - reloadChannels(): Reconnect affected channels
// - reloadBrowser(): Reinitialize browser profilesSummary
- Configuration is loaded from
~/.openclaw/openclaw.json, validated using Zod - chokidar watches for file changes with 300ms debounce to batch rapid modifications
- Three reload strategies: restart (full restart), hot (runtime reload), none (ignore)
- Hooks, Cron, Browser, and some channels support hot-reload
- Plugins and Gateway core config require a full restart
- Runtime configuration is modified via
config.patch, taking effect immediately without persistence
Next: Channels Overview