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