nikivdev/code · error

invalid lifecycle.domains.engine '{}': expected 'docker' or

Error message

invalid lifecycle.domains.engine '{}': expected 'docker' or 'native'

What it means

parse_domains_engine validates the lifecycle.domains.engine string from flow.toml, accepting only 'docker' or 'native' (case-insensitive, trimmed). Any other value bails with this message echoing the offending value. It prevents silently running domains with an unknown engine.

Source

Thrown at src/lifecycle.rs:237

}

fn remove_lifecycle_route(engine: Option<DomainsEngineArg>, host: &str) -> Result<()> {
    domains::run(DomainsCommand {
        engine,
        action: Some(DomainsAction::Rm(DomainsRmOpts {
            host: host.to_string(),
        })),
    })
}

fn parse_domains_engine(raw: Option<&str>) -> Result<Option<DomainsEngineArg>> {
    let Some(raw) = raw else {
        return Ok(None);
    };
    let engine = match raw.trim().to_ascii_lowercase().as_str() {
        "docker" => DomainsEngineArg::Docker,
        "native" => DomainsEngineArg::Native,
        other => bail!(
            "invalid lifecycle.domains.engine '{}': expected 'docker' or 'native'",
            other
        ),
    };
    Ok(Some(engine))
}

fn resolve_project_config(config_arg: &Path) -> Result<ProjectConfig> {
    let cwd = std::env::current_dir().context("Failed to read current directory")?;
    let flow_path = resolve_flow_path(config_arg, &cwd)?;
    let cfg = config::load(&flow_path)
        .with_context(|| format!("Failed to load {}", flow_path.display()))?;
    Ok(ProjectConfig {
        flow_path,
        config: cfg,
    })
}

View on GitHub (pinned to a747e741ae)

Solutions

  1. Set engine = "docker" in [lifecycle.domains] if you use Docker
  2. Set engine = "native" if you want native process management
  3. Remove the engine key if the default is acceptable, or install the engine you intended and use its supported name

Example fix

// before (flow.toml)
[lifecycle.domains]
engine = "podman"
// after
[lifecycle.domains]
engine = "docker"
Defensive patterns

Strategy: validation

Validate before calling

let cfg = std::fs::read_to_string("flow.toml")?;
if let Some(line) = cfg.lines().find(|l| l.trim_start().starts_with("engine")) {
    let v = line.split('=').nth(1).unwrap_or("").trim().trim_matches('"');
    if !matches!(v.to_ascii_lowercase().as_str(), "docker" | "native") {
        eprintln!("invalid lifecycle.domains.engine: {}", v);
    }
}

Type guard

fn is_valid_engine(v: &str) -> bool {
    matches!(v.trim().to_ascii_lowercase().as_str(), "docker" | "native")
}

Try / catch

match ensure_domains_up(&cfg).await {
    Err(e) if e.to_string().contains("invalid lifecycle.domains.engine") => {
        eprintln!("Set engine to 'docker' or 'native' in flow.toml [lifecycle.domains]");
    }
    other => other?,
}

Prevention

When it happens

Trigger: flow.toml contains [lifecycle.domains] engine = "podman" (or "compose", "Docker", "k8s", etc.) and ensure_domains_up or run_domains_down parses the config.

Common situations: Assuming other container engines are supported; accidental whitespace/case usually fine (trimmed/lowercased) but synonyms like 'container' fail; copying config from a different tool with different engine names.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/ea48b9d55fd2b649. Report an issue: GitHub.