jdx/mise · error

bootstrap compose project

Error message

bootstrap compose project '{name}' oneshot services must also appear in services

What it means

Thrown during TOML validation when the `oneshot` list names services that are not present in the project's `services` list. Oneshot services are started and shut down around a task run, so they must be members of the project's service set; the library rejects dangling ones.

Solutions

  1. Add the missing service names to the `services` list
  2. Fix the spelling of the oneshot entries so they match `services`

Example fix

# before
[system.compose.myproj]
services = ["db", "api"]
oneshot = ["migrate"]
# after
[system.compose.myproj]
services = ["db", "api", "migrate"]
oneshot = ["migrate"]
Defensive patterns

Strategy: validation

Validate before calling

let missing: Vec<_> = cfg.oneshot.iter()
    .filter(|s| !cfg.services.contains(s))
    .collect();
assert!(missing.is_empty(), "oneshot not in services: {missing:?}");

Prevention

When it happens

Trigger: A `[system.compose.<name>]` block with a non-empty `services` list where at least one entry of `oneshot` does not appear in `services`. Raised from `from_toml_with_origin` at parse time. Note: only checked when `services` is non-empty.

Common situations: Typo in a oneshot service name; adding a one-shot helper container to `oneshot` but forgetting to also list it under `services`; renaming a service in one list but not the other.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/system/compose.rs:360

        {
            bail!(
                "bootstrap compose project '{name}' down_volumes and down_images require state = \"absent\""
            );
        }
        if config.state != ComposeState::Running && config.renew_anonymous_volumes {
            bail!(
                "bootstrap compose project '{name}' renew_anonymous_volumes requires state = \"running\""
            );
        }
        let explicit_dependencies = config
            .depends_on
            .iter()
            .map(|dependency| parse_dependency(dependency))
            .collect::<Result<Vec<_>>>()?;
        let services = dedupe(config.services);
        let oneshot: IndexSet<String> = dedupe(config.oneshot).into_iter().collect();
        if !services.is_empty() && oneshot.iter().any(|service| !services.contains(service)) {
            bail!(
                "bootstrap compose project '{name}' oneshot services must also appear in services"
            );
        }
        let files = resolve_paths(&config.project_dir, config.files);
        let env_files = resolve_paths(&config.project_dir, config.env_files);
        let path_dependencies = std::iter::once(ResourceId::new(
            "directory",
            config.project_dir.to_string_lossy(),
        ))
        .chain(
            files
                .iter()
                .chain(&env_files)
                .map(|path| ResourceId::new("file", path.to_string_lossy())),
        )
        .collect::<IndexSet<_>>()
        .into_iter()
        .collect();

View on GitHub (pinned to 533346cc37)