Skip to content

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:

typescript
// 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 ​

json
{
  "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 ​

typescript
// 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 CategoryReload TypeDescription
Plugin configrestartPlugin registry needs to be reloaded
Gateway core configrestartCore parameter changes (port, auth)
Hooks confighotRe-register hooks at runtime
Cron confighotReschedule cron jobs at runtime
Browser confighotReinitialize browser profiles
Channel confighotReload on a per-channel basis
Identity confignoneTakes effect on next session
Wizard confignoneOnly used during initialization
Logging confignoneRequires manual restart
Model confignoneTakes effect at session level

Channel-Specific Reload Rules ​

Different channels have different reload requirements:

typescript
// 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 ​

typescript
// 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:

typescript
// 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:

typescript
// Configuration validation
// Each section has its own Zod schema
// Invalid configs are rejected with descriptive error messages

Reload Handlers ​

Source: src/gateway/server-reload-handlers.ts

Hot-reload is handled by dedicated reload handlers:

typescript
// 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 profiles

Summary ​

  • 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

OpenClaw Source Code Tutorial