{"record":{"id":"751069b6958e9943","repo":"jdx/mise","slug":"bootstrap-compose-project-name-services-cannot","errorCode":null,"errorMessage":"bootstrap compose project '{name}' services cannot be combined with state = \"absent\" because compose down removes the entire project","messagePattern":"bootstrap compose project '(.+?)' services cannot be combined with state = \"absent\" because compose down removes the entire project","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":287,"sourceCode":"impl ComposeRequest {\n    fn from_toml(name: String, config: ComposeTomlConfig) -> Result<Self> {\n        if name.is_empty() {\n            bail!(\"bootstrap compose project names cannot be empty\");\n        }\n        if !config.project_dir.is_absolute() {\n            bail!(\n                \"bootstrap compose project '{name}' project_dir must be absolute: {}\",\n                config.project_dir.display()\n            );\n        }\n        validate_project_name(config.project_name.as_deref())?;\n        validate_values(\"profile\", &config.profiles)?;\n        validate_values(\"service\", &config.services)?;\n        validate_values(\"oneshot service\", &config.oneshot)?;\n        validate_command(\"command\", &config.command)?;\n        validate_command(\"engine_command\", &config.engine_command)?;\n        if config.state == ComposeState::Absent && !config.services.is_empty() {\n            bail!(\n                \"bootstrap compose project '{name}' services cannot be combined with state = \\\"absent\\\" because compose down removes the entire project\"\n            );\n        }\n        if !config.wait && config.wait_timeout.is_some() {\n            bail!(\"bootstrap compose project '{name}' wait_timeout requires wait = true\");\n        }\n        if config.wait_timeout == Some(0) {\n            bail!(\"bootstrap compose project '{name}' wait_timeout must be greater than zero\");\n        }\n        if config.state != ComposeState::Absent\n            && (config.down_volumes || config.down_images.is_some())\n        {\n            bail!(\n                \"bootstrap compose project '{name}' down_volumes and down_images require state = \\\"absent\\\"\"\n            );\n        }\n        if config.state != ComposeState::Running && config.renew_anonymous_volumes {\n            bail!(","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/compose.rs#L269-L305","documentation":"With `state = \"absent\"`, mise converges by running `docker compose down`, which removes the entire project — every service, network, and (per flags) volumes — not just the services you list. Because per-service selection cannot be honored on removal, combining `services` with absent state is rejected at config parse time.","triggerScenarios":"A compose table sets both `state = \"absent\"` and a non-empty `services = [...]` (or oneshot services) list. `ComposeRequest::from_toml` bails during `mise bootstrap compose plan`/`apply` config parsing.","commonSituations":"Reusing one project block for both 'bring up selected services' and 'tear down' by flipping `state` while leaving `services` populated; copy-paste of a running project's config with only the state changed.","solutions":["To remove the whole project: delete the `services`/`oneshot` lists from the absent-state table.","To keep only selected services running: set `state = \"running\"` and keep the `services` list.","If you need a separate teardown definition, use a distinct `[bootstrap.compose.<name>]` table with `state = \"absent\"` and no services."],"exampleFix":"# before\n[bootstrap.compose.web]\nproject_dir = \"/srv/web\"\nstate = \"absent\"\nservices = [\"api\"]\n\n# after\n[bootstrap.compose.web]\nproject_dir = \"/srv/web\"\nstate = \"absent\"","handlingStrategy":"validation","validationCode":"if cfg.state == ComposeState::Absent {\n    assert!(cfg.services.is_empty() && cfg.oneshot.is_empty(),\n        \"services/oneshot cannot be combined with state = absent\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a dedicated teardown table (state = \"absent\", no services) separate from running tables.","When flipping a project's state, clear service selection lists at the same time."],"tags":["mise","bootstrap","compose","config","conflicting-options","docker"],"backgroundTag":"conflicting-config-options","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}