{"record":{"id":"9cf70a4df17c44e2","repo":"jdx/mise","slug":"bootstrap-compose-project-name-wait-timeout-mu","errorCode":null,"errorMessage":"bootstrap compose project '{name}' wait_timeout must be greater than zero","messagePattern":"bootstrap compose project '(.+?)' wait_timeout must be greater than zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":295,"sourceCode":"                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!(\n                \"bootstrap compose project '{name}' renew_anonymous_volumes requires state = \\\"running\\\"\"\n            );\n        }\n        let explicit_dependencies = config\n            .depends_on\n            .iter()\n            .map(|dependency| parse_dependency(dependency))\n            .collect::<Result<Vec<_>>>()?;","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/compose.rs#L277-L313","documentation":"`wait_timeout` is passed as a duration to the wait logic; a zero timeout would either fail instantly or wait forever depending on interpretation, so `ComposeRequest::from_toml` rejects `wait_timeout = 0` explicitly.","triggerScenarios":"A compose table sets `wait_timeout = 0` (with `wait = true` set or not — the zero check runs after the wait-pairing check).","commonSituations":"Using 0 to mean 'no limit' or 'disabled' — this config does not support that meaning; leftover placeholder values from templating.","solutions":["Set a positive timeout appropriate to your healthchecks, e.g. `wait_timeout = 300`.","If you intended no waiting at all, remove `wait_timeout` (and `wait`)."],"exampleFix":"# before\n[bootstrap.compose.web]\nproject_dir = \"/srv/web\"\nwait = true\nwait_timeout = 0\n\n# after\n[bootstrap.compose.web]\nproject_dir = \"/srv/web\"\nwait = true\nwait_timeout = 300","handlingStrategy":"validation","validationCode":"if let Some(t) = cfg.wait_timeout {\n    assert!(t > 0, \"wait_timeout must be > 0, got {t}\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["There is no '0 = unlimited' semantics; size the timeout to your slowest healthcheck plus margin.","Use timeouts derived from real `docker compose up --wait` observations, not placeholder 0s."],"tags":["mise","bootstrap","compose","config","wait","validation"],"backgroundTag":"invalid-option-value","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}