jdx/mise · error
bootstrap compose project '{name}' project_dir must be absol
Error message
bootstrap compose project '{name}' project_dir must be absolute: {} What it means
`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.
Source
Thrown at src/system/compose.rs:275
dry_run_actions
.get(&request.name)
.copied()
.filter(|action| {
matches!(
action,
ResourceAction::Create | ResourceAction::Update | ResourceAction::Remove
)
})
.unwrap_or(action)
}
impl ComposeRequest {
fn from_toml(name: String, config: ComposeTomlConfig) -> Result<Self> {
if name.is_empty() {
bail!("bootstrap compose project names cannot be empty");
}
if !config.project_dir.is_absolute() {
bail!(
"bootstrap compose project '{name}' project_dir must be absolute: {}",
config.project_dir.display()
);
}
validate_project_name(config.project_name.as_deref())?;
validate_values("profile", &config.profiles)?;
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");
}View on GitHub (pinned to 9dcfcaa0dc)
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.
Example fix
# before [bootstrap.compose.web] project_dir = "./docker" # after [bootstrap.compose.web] project_dir = "/srv/myapp/docker"
Defensive patterns
Strategy: validation
Validate before calling
let dir = std::path::Path::new(&cfg.project_dir);
assert!(dir.is_absolute(), "project_dir must be absolute: {}", dir.display()); Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- bootstrap user '{name}' {field} must be an absolute path
- bootstrap compose project names cannot be empty
- bootstrap compose project '{name}' services cannot be combin
- bootstrap compose project '{name}' wait_timeout requires wai
- bootstrap compose project '{name}' wait_timeout must be grea
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/58ee0d9237268398.
Report an issue: GitHub.