jdx/mise · error
bootstrap compose project '{name}' down_volumes and down_ima
Error message
bootstrap compose project '{name}' down_volumes and down_images require state = "absent" What it means
`down_volumes` and `down_images` map to `docker compose down` flags (`-v` and `--rmi`), and `down` only runs when a project is being removed. `ComposeRequest::from_toml` therefore rejects these teardown options on a table whose `state` is not `"absent"`.
Source
Thrown at src/system/compose.rs:300
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"
);
}
if !config.wait && config.wait_timeout.is_some() {
bail!("bootstrap compose project '{name}' wait_timeout requires wait = true");
}
if config.wait_timeout == Some(0) {
bail!("bootstrap compose project '{name}' wait_timeout must be greater than zero");
}
if config.state != ComposeState::Absent
&& (config.down_volumes || config.down_images.is_some())
{
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"View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Remove `down_volumes`/`down_images` from running-state tables.
- If you want cleanup on removal, put them on the `state = "absent"` definition of that project.
- Re-run `mise bootstrap compose plan` to confirm the config parses.
Example fix
# before [bootstrap.compose.web] project_dir = "/srv/web" state = "running" down_volumes = true # after [bootstrap.compose.web] project_dir = "/srv/web" state = "running"
Defensive patterns
Strategy: validation
Validate before calling
if cfg.state != ComposeState::Absent {
assert!(!cfg.down_volumes && cfg.down_images.is_none(),
"down_volumes/down_images only valid with state = absent");
} Prevention
- Think of down_volumes/down_images as `docker compose down` flags — they belong only on absent-state tables.
- Review copied compose blocks for leftover teardown options when changing state.
When it happens
Trigger: A compose table with `state = "running"` (or any non-absent state) sets `down_volumes = true` and/or `down_images = "all"|"local"`.
Common situations: Copying a known-good teardown block and flipping only `state` back to running; intending 'prune volumes/images on every converge', which this config does not express.
Related errors
- bootstrap compose project '{name}' services cannot be combin
- bootstrap compose project '{name}' renew_anonymous_volumes r
- bootstrap compose project names cannot be empty
- bootstrap compose project '{name}' project_dir must be absol
- bootstrap compose project '{name}' wait_timeout requires wai
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/0197947fdcf79573.
Report an issue: GitHub.