jdx/mise · error

bootstrap compose project names cannot be empty

Error message

bootstrap compose project names cannot be empty

What it means

When parsing a bootstrap compose declaration from TOML, the project name key must be a non-empty string. An empty name (e.g. [bootstrap.compose."] or name = "") cannot identify a compose project, so from_toml_with_origin bails immediately.

Solutions

  1. Give the compose project a non-empty name in the TOML key
  2. Remove the empty placeholder section if it was left by a template
  3. Check any script that generates the config for an unset/empty variable

Example fix

# before
[bootstrap.compose."]
project_dir = "/srv/app"

# after
[bootstrap.compose.app-db]
project_dir = "/srv/app"
Defensive patterns

Strategy: validation

Validate before calling

def validate_compose_names(config: dict) -> None:
    for name in config.get("bootstrap", {}).get("compose", {}):
        if not name:
            raise ValueError("bootstrap compose project names cannot be empty")

Prevention

When it happens

Trigger: A config file contains an empty compose project key under [bootstrap.compose], or programmatic construction passes an empty `name` string to from_toml_with_origin.

Common situations: Template/generated config left a placeholder key; a TOML table written as [bootstrap.compose."] after an editor mangled it; a script interpolated an unset variable into the section name.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/4ef0d1771990cd08. Report an issue: GitHub.

Appendix: source

Thrown at src/system/compose.rs:315

                ResourceAction::Create | ResourceAction::Update | ResourceAction::Remove
            )
        })
        .unwrap_or(action)
}

impl ComposeRequest {
    #[cfg(test)]
    fn from_toml(name: String, config: ComposeTomlConfig) -> Result<Self> {
        Self::from_toml_with_origin(name, config, None)
    }

    fn from_toml_with_origin(
        name: String,
        config: ComposeTomlConfig,
        origin: Option<ResourceOrigin>,
    ) -> Result<Self> {
        if name.is_empty() {
            bail!("bootstrap compose project names cannot be empty");
        }
        if !config.project_dir.is_absolute() {
            bail!(
                "bootstrap compose project '{name}' project_dir must be absolute: {}",
                config.project_dir.display()
            );
        }
        validate_project_name(config.project_name.as_deref())?;
        validate_values("profile", &config.profiles)?;
        validate_values("service", &config.services)?;
        validate_values("oneshot service", &config.oneshot)?;
        validate_command("command", &config.command)?;
        validate_command("engine_command", &config.engine_command)?;
        if config.state == ComposeState::Absent && !config.services.is_empty() {
            bail!(
                "bootstrap compose project '{name}' services cannot be combined with state = \"absent\" because compose down removes the entire project"
            );
        }

View on GitHub (pinned to 533346cc37)