{"record":{"id":"58ee0d9237268398","repo":"jdx/mise","slug":"bootstrap-compose-project-name-project-dir-mus","errorCode":null,"errorMessage":"bootstrap compose project '{name}' project_dir must be absolute: {}","messagePattern":"bootstrap compose project '(.+?)' project_dir must be absolute: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":275,"sourceCode":"    dry_run_actions\n        .get(&request.name)\n        .copied()\n        .filter(|action| {\n            matches!(\n                action,\n                ResourceAction::Create | ResourceAction::Update | ResourceAction::Remove\n            )\n        })\n        .unwrap_or(action)\n}\n\nimpl 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        }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/compose.rs#L257-L293","documentation":"`ComposeRequest::from_toml` requires `project_dir` to be absolute. The directory is the anchor for resolving `files` and `env_files` and becomes a directory resource dependency, and the privileged apply step needs an unambiguous location, so relative project directories are rejected at parse time with the offending path echoed.","triggerScenarios":"A compose table sets `project_dir = \"./docker\"`, `project_dir = \"stack\"`, or `project_dir = \"~/apps/web\"` — none satisfy `Path::is_absolute()` (mise does not expand `~` or cwd-relative paths here).","commonSituations":"Porting a docker-compose invocation that was always run from the repo; assuming mise resolves paths relative to the mise.toml file (it does not for this field); using `~` because that reads naturally in dotfiles configs.","solutions":["Spell the directory from the root: `project_dir = \"/srv/myapp/docker\"`.","Do not use `~`, `./`, or bare relative names; expand them yourself (e.g. via a config template) if you need host-dependent roots.","Re-run `mise bootstrap compose plan` to confirm parsing and see the resolved file dependencies."],"exampleFix":"# before\n[bootstrap.compose.web]\nproject_dir = \"./docker\"\n\n# after\n[bootstrap.compose.web]\nproject_dir = \"/srv/myapp/docker\"","handlingStrategy":"validation","validationCode":"let dir = std::path::Path::new(&cfg.project_dir);\nassert!(dir.is_absolute(), \"project_dir must be absolute: {}\", dir.display());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write project_dir from the filesystem root; '~' and './' are never expanded for it.","For host-dependent roots, resolve the absolute path in a template (e.g. {{ env.HOME }}) rather than relying on relative resolution."],"tags":["mise","bootstrap","compose","path-validation","config"],"backgroundTag":"absolute-path-required","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}