# How Configuration Changes Are Applied in Continuedev/Continue: The Complete Pipeline

> Understand how continuedev/continue applies configuration changes via a centralized cascade. Learn about ConfigHandler.cascadeInit, reloadConfig, YAML unrolling, and listener notifications.

- Repository: [Continue/continue](https://github.com/continuedev/continue)
- Tags: internals
- Published: 2026-06-18

---

**Configuration changes in Continue are applied through a centralized cascade that begins with `ConfigHandler.cascadeInit` and converges on `reloadConfig`, which unrolls the YAML configuration, refreshes the active profile, and notifies all registered listeners.**

The Continue coding assistant maintains a dynamic runtime configuration using an **Assistant Unrolled** YAML definition or remote assistant slug. Whenever you edit a configuration file, switch profiles, or trigger a refresh from the VS Code extension or CLI, the system executes a precise pipeline to ensure consistency across the core engine and UI components.

## Configuration Discovery and Source Resolution

The process begins with determining where the configuration originates. In [`extensions/cli/src/configLoader.ts`](https://github.com/continuedev/continue/blob/main/extensions/cli/src/configLoader.ts), the `loadConfiguration` function (lines 53-62) implements a strict priority hierarchy:

1. **CLI flag** `--config` (highest priority)
2. **Saved URI** in the authentication record
3. **Local file** at `~/.continue/config.yaml`
4. **Remote default** configuration (fallback)

This function returns both the unrolled assistant object and a `ConfigSource` enum that tracks the provenance of the configuration. The loader handles YAML parsing, remote fetching, and initial validation before the configuration enters the core system.

## ConfigHandler Architecture and Initialization

When the Continue core starts, it instantiates a `ConfigHandler` (defined in [`core/config/ConfigHandler.ts`](https://github.com/continuedev/continue/blob/main/core/config/ConfigHandler.ts), lines 52-63). This singleton coordinates all configuration state through two critical components:

- **Global Profile Manager** (`globalLocalProfileManager`): Manages profile definitions across workspaces
- **Profile Lifecycle Management**: Loads local profiles via `loadProfiles` → `getLocalProfiles`

The constructor establishes the foundation for reactive updates, preparing the system to handle multiple concurrent configuration sources while maintaining isolation between workspace contexts.

## The Configuration Cascade Process

### Top-Level Initialization with cascadeInit

The `ConfigHandler.cascadeInit` method serves as the entry point for all configuration refreshes. Called during startup and whenever `refreshAll` triggers (lines 96-98), this method:

- Reloads workspace identifiers
- Recreates the global profile manager
- Determines the currently selected profile (persisted per workspace)
- Invokes `reloadConfig` for the active profile

This cascading approach ensures that workspace-specific settings remain isolated while global configuration changes propagate consistently.

### Profile Selection and Workspace Isolation

Continue supports multiple profiles (local YAML files or remote assistants) that can be switched per workspace. The `ConfigHandler` maintains the active profile selection and routes all reload requests through the specific `ProfileLifecycleManager` instance associated with that profile.

## The Single Point of Truth: reloadConfig

The `ConfigHandler.reloadConfig` method (lines 33-84 in [`core/config/ConfigHandler.ts`](https://github.com/continuedev/continue/blob/main/core/config/ConfigHandler.ts)) represents the **exclusive location where configuration changes take effect**. This method implements a rigorous sequence:

1. **Early abort validation**: Returns `configLoadInterrupted` if no profile is selected
2. **Stale data cleanup**: Calls `clearConfig()` on all inactive profiles (lines 51-57) to prevent memory leaks and state pollution
3. **Active profile reload**: Invokes `this.currentProfile.reloadConfig(this.additionalContextProviders)` (lines 62-64), which re-parses the YAML or fetches the remote assistant
4. **Error injection**: Applies any external validation errors via optional `injectErrors`
5. **Listener notification**: Executes `notifyConfigListeners` (lines 70-73), iterating over callbacks registered through `onConfigUpdate`
6. **Event emission**: Calls `this.initter.emit("init")` to resolve awaiting promises
7. **Diagnostics logging**: Increments `totalConfigReloads` and records duration metrics via `Logger.error` if validation fails (lines 74-76)

This centralized approach guarantees that every component receives the identical configuration state simultaneously.

## Propagation to UI and CLI Components

Both the VS Code extension and CLI interface subscribe to the `ConfigHandler` to react to changes dynamically.

### VS Code Extension Integration

The VS Code extension registers a listener during initialization to update UI state:

```typescript
// extensions/vscode/src/extension/VsCodeExtension.ts
this.configHandler.onConfigUpdate(({ config, errors }) => {
  if (config) {
    // Refresh the autocomplete provider with new model settings
    this.completionProvider.updateConfig(config);
  }
  if (errors?.length) {
    this.showErrorToast(errors.map(e => e.message).join("\n"));
  }
});

```

### CLI Configuration Service

The CLI triggers reloads when detecting filesystem changes:

```typescript
// extensions/cli/src/services/ConfigService.ts
import { ConfigHandler } from "@continuedev/continue/core/config/ConfigHandler";

export async function applyUserChanges(
  configHandler: ConfigHandler,
  changedFilePath: string,
) {
  // User edited ~/.continue/config.yaml; trigger core pickup
  await configHandler.reloadConfig(`User edited ${changedFilePath}`);
}

```

## End-to-End Configuration Change Flows

Different user actions trigger distinct paths through the pipeline:

- **CLI flag override**: Running `continue --config my-assistant.yaml` forces `loadConfiguration` to select the CLI source, immediately invoking `reloadConfig` with the new unrolled configuration
- **Local file editing**: File watchers in [`VsCodeExtension.ts`](https://github.com/continuedev/continue/blob/main/VsCodeExtension.ts) detect changes to `~/.continue/config.yaml` and call `reloadConfig("config file changed")`, reloading via `loadLocalConfigYaml`
- **Authentication changes**: Signing in to a new Continue.org account updates the saved URI, triggering `refreshAll` → `cascadeInit` → `reloadConfig` with the remote default config
- **Custom context provider registration**: When `ConfigHandler.registerCustomContextProvider` executes, it immediately calls `reloadConfig("Custom context provider registered")`, clearing existing profiles and merging the provider into the active configuration

## Summary

- **Centralized reloading**: All configuration changes converge on `ConfigHandler.reloadConfig` in [`core/config/ConfigHandler.ts`](https://github.com/continuedev/continue/blob/main/core/config/ConfigHandler.ts), ensuring single-source-of-truth semantics
- **Hierarchical discovery**: `loadConfiguration` resolves sources via CLI flags → auth records → local YAML → remote defaults
- **Profile isolation**: The system maintains separate `ProfileLifecycleManager` instances per workspace, clearing inactive profiles during reloads to prevent state contamination
- **Reactive updates**: UI components subscribe via `onConfigUpdate` to receive fresh `ContinueConfig` objects and validation errors immediately after unrolling
- **Diagnostic tracking**: Every reload increments `totalConfigReloads` and logs duration metrics for performance monitoring

## Frequently Asked Questions

### What triggers a configuration reload in Continue?

Any modification to the runtime environment triggers `reloadConfig`, including manual edits to `~/.continue/config.yaml`, CLI flag overrides, profile switches, authentication state changes, or the registration of custom context providers. Both the VS Code extension and CLI implement file watchers and event listeners that invoke `ConfigHandler.reloadConfig` with descriptive reasons for the refresh.

### Where does Continue look for configuration files?

According to [`extensions/cli/src/configLoader.ts`](https://github.com/continuedev/continue/blob/main/extensions/cli/src/configLoader.ts), Continue checks sources in strict priority order: first the `--config` CLI flag, then a saved URI in the authentication record, followed by the local file at `~/.continue/config.yaml` (resolved via [`core/util/paths.ts`](https://github.com/continuedev/continue/blob/main/core/util/paths.ts)), and finally the remote default configuration. This hierarchy ensures that explicit user overrides take precedence over automatic fallbacks.

### How does Continue handle multiple configuration profiles?

The `ConfigHandler` maintains a `globalLocalProfileManager` that loads all available profiles during initialization. When `cascadeInit` executes, it determines the active profile for the current workspace and calls `reloadConfig` specifically for that profile. Inactive profiles have `clearConfig()` called on them during the reload process (lines 51-57) to ensure they do not consume resources or leak state into the active configuration.

### Can extensions receive validation errors when configuration changes?

Yes. The `onConfigUpdate` listener receives an object containing both the `config` and an `errors` array. If `loadConfiguration` or the unrolling process encounters validation failures, these errors propagate through `notifyConfigListeners` (lines 70-73) and are delivered to all subscribed UI components, which can then display toast notifications or error panels to the user.