Home Assistant Runtime Configuration Structure and Runner Injection

The RuntimeConfig dataclass bundles all command-line flags and environment settings into a single immutable object that flows from the CLI parser through homeassistant/runner.py to homeassistant/bootstrap.py, where individual fields populate the core HomeAssistant config object.

The home-assistant/core repository uses a centralized runtime configuration pattern to manage startup parameters cleanly. When you launch Home Assistant via the hass command, your arguments are encapsulated in a RuntimeConfig instance that travels unchanged through the initialization pipeline. This design ensures that configuration directory paths, logging preferences, and debug flags remain consistent from process startup through core initialization.

RuntimeConfig Dataclass Structure

The RuntimeConfig class is defined in homeassistant/runner.py using @dataclasses.dataclass(slots=True), creating a lightweight immutable container. It aggregates every launch parameter required to configure the core application:

  • config_dir: Path to the configuration directory (defaults to /config)
  • skip_pip: Boolean to disable automatic installation of missing Python dependencies
  • skip_pip_packages: List of specific pip packages to skip during setup
  • recovery_mode: Boolean forcing recovery mode when configuration parsing fails
  • verbose: Boolean enabling verbose logging output
  • log_rotate_days: Optional integer specifying retention days for log files
  • log_file: Optional string path for the destination log file
  • log_no_color: Boolean disabling color codes in terminal output
  • debug: Boolean running the event loop in debug mode and setting hass.config.debug
  • open_ui: Boolean triggering browser opening after core startup
  • safe_mode: Boolean starting Home Assistant in safe mode with most integrations disabled

Configuration Flow from CLI to Core

CLI Construction

The command-line parser in homeassistant/__main__.py constructs a RuntimeConfig instance from supplied flags and environment variables. This object serves as the single source of truth for the entire startup sequence.

Runner Entry Point

The run() function in homeassistant/runner.py receives the RuntimeConfig and initializes the asyncio environment:

_enable_posix_spawn()
set_open_file_descriptor_limit()
asyncio.set_event_loop_policy(
    HassEventLoopPolicy(runtime_config.debug)
)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop.run_until_complete(
    setup_and_run_hass(runtime_config)
)

The debug flag is immediately handed to HassEventLoopPolicy, which configures the asyncio loop for debug tracing before the core initializes.

Bootstrap Initialization

Inside setup_and_run_hass(), the coroutine forwards RuntimeConfig to bootstrap.async_setup_hass() in homeassistant/bootstrap.py. The bootstrap layer extracts individual fields to configure the HomeAssistant core object:

hass = core.HomeAssistant(runtime_config.config_dir)
...
hass.config.debug = runtime_config.debug
hass.config.safe_mode = runtime_config.safe_mode
hass.config.skip_pip = runtime_config.skip_pip
hass.config.skip_pip_packages = runtime_config.skip_pip_packages

This wiring occurs early in async_setup_hass, before any integrations load, ensuring the core configuration object reflects command-line intentions.

Logging Configuration

The bootstrap module forwards logging-related fields (verbose, log_rotate_days, log_file, log_no_color) to async_enable_logging, configuring the root logger before component initialization begins.

Core Execution

After bootstrap completes, setup_and_run_hass calls await hass.async_run(), which starts the core event loop, background tasks, and HTTP/Web UI using the parameters propagated from the original RuntimeConfig.

Practical Implementation Examples

Manually Building RuntimeConfig

For tests or custom scripts, you can manually construct a RuntimeConfig and invoke the runner directly:

from homeassistant.runner import RuntimeConfig, run

# Minimal configuration pointing to an existing config directory

config = RuntimeConfig(
    config_dir="/home/user/.homeassistant",
    verbose=True,
    debug=True,
    safe_mode=False,
    log_file="/tmp/hass.log",
)

# Run Home Assistant in the current process (blocking until exit)

exit_code = run(config)
print("Home Assistant terminated with code", exit_code)

This mirrors how the internal hass command creates the configuration object.

Accessing Config in Integrations

Custom integrations access runtime parameters through the hass.config object, which received values from RuntimeConfig during bootstrap:

def async_setup_entry(hass, entry):
    # Values propagated from original RuntimeConfig by bootstrap.async_setup_hass

    if hass.config.debug:
        _LOGGER.debug("Running in debug mode")
    if hass.config.safe_mode:
        _LOGGER.info("Safe mode active – only core integrations loading")
    return True

Note that integrations cannot access the original RuntimeConfig directly; they must use the hass.config namespace.

Key Source Files

Summary

  • RuntimeConfig is an immutable dataclass defined in homeassistant/runner.py that encapsulates all startup parameters including paths, logging settings, and mode flags.
  • The configuration flows unidirectionally from CLI parser → run() → setup_and_run_hass() → bootstrap.async_setup_hass().
  • The bootstrap layer maps RuntimeConfig fields to hass.config attributes, making them available to integrations.
  • The debug flag immediately affects the asyncio event loop policy before core initialization.
  • Direct instantiation of RuntimeConfig allows programmatic Home Assistant startup for testing and custom deployments.

Frequently Asked Questions

What is the RuntimeConfig class in Home Assistant?

RuntimeConfig is a Python dataclass defined in homeassistant/runner.py that acts as an immutable container for all command-line arguments and environment settings required to launch Home Assistant. It uses slots=True for memory efficiency and contains fields for configuration directories, logging options, and operational modes like safe mode or debug mode.

How does the debug flag affect the event loop?

When runtime_config.debug is True, the runner passes this flag to HassEventLoopPolicy in homeassistant/runner.py, which configures the asyncio event loop for debug tracing before the loop is created. This enables warnings for slow callbacks and unawaited coroutines during the core initialization phase.

Can integrations access the original RuntimeConfig object?

No, integrations cannot access the original RuntimeConfig instance directly. The bootstrap module in homeassistant/bootstrap.py extracts values from RuntimeConfig and assigns them to the hass.config object during async_setup_hass(). Integrations must read runtime parameters from hass.config attributes such as hass.config.debug or hass.config.safe_mode.

Where is the configuration directory path defined during startup?

The config_dir path originates from command-line arguments parsed in homeassistant/__main__.py, is stored in RuntimeConfig, and passed to core.HomeAssistant(runtime_config.config_dir) in homeassistant/bootstrap.py. This occurs early in the bootstrap sequence, establishing the base path for all YAML configuration files and storage directories.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →