jdx/mise · error · eyre::Report
bootstrap compose project '{name}' oneshot services must als
Error message
bootstrap compose project '{name}' oneshot services must also appear in services What it means
`oneshot` marks services that should be run to completion (migrations, seeds) rather than kept running; mise launches them from the same service set as the normal `services` selection. `ComposeRequest::from_toml` therefore requires every oneshot entry to appear in `services` when an explicit `services` list is set.
Source
Thrown at src/system/compose.rs:317
{
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 9dcfcaa0dc)
Solutions
- Add the missing oneshot service to `services`: `services = ["api", "worker", "migrate"]`.
- Or drop it from `oneshot` if it should not be converged by this project.
- Cross-check both lists against `docker compose config --services` output for the project.
Example fix
# before [bootstrap.compose.web] project_dir = "/srv/web" services = ["api", "worker"] oneshot = ["migrate"] # after [bootstrap.compose.web] project_dir = "/srv/web" services = ["api", "worker", "migrate"] oneshot = ["migrate"]
Defensive patterns
Strategy: validation
Validate before calling
let services: std::collections::HashSet<&String> = cfg.services.iter().collect();
for one in &cfg.oneshot {
assert!(services.contains(one), "oneshot service '{one}' missing from services");
} Prevention
- Add every oneshot service to the services list in the same edit.
- Cross-check services/oneshot against `docker compose config --services` when the compose file changes.
When it happens
Trigger: A compose table sets `services = ["api", "worker"]` and `oneshot = ["migrate"]` — `migrate` is not in `services`, so parsing bails. (When `services` is empty all configured services are implied, and the check is skipped.)
Common situations: Forgetting to add the migration/seed service to the selected services list; renaming a service in the compose file but only updating one of the two lists.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- bootstrap compose project names cannot be empty
- bootstrap compose project '{name}' wait_timeout requires wai
- bootstrap compose project '{name}' wait_timeout must be grea
- bootstrap compose project '{name}' project_dir must be absol
- bootstrap compose project '{name}' services cannot be combin
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/8093fcb9691811b2.
Report an issue: GitHub.