{"record":{"id":"a5491f64ba6b08bb","repo":"jdx/mise","slug":"command-does-not-exist","errorCode":null,"errorMessage":"command does not exist: {}","messagePattern":"command does not exist: (.+?)","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":1045,"sourceCode":"        .into_iter()\n        .map(|path| {\n            if path.is_absolute() {\n                path\n            } else {\n                project_dir.join(path)\n            }\n        })\n        .collect()\n}\n\nfn resolve_command(command: &[String]) -> Result<Vec<String>> {\n    let (program, args) = command\n        .split_first()\n        .ok_or_else(|| eyre!(\"command cannot be empty\"))?;\n    let resolved = if Path::new(program).is_absolute() {\n        let path = PathBuf::from(program);\n        if !path.is_file() {\n            bail!(\"command does not exist: {}\", path.display());\n        }\n        path\n    } else {\n        crate::file::which(program).ok_or_else(|| eyre!(\"command not found: {program}\"))?\n    };\n    Ok(std::iter::once(resolved.to_string_lossy().to_string())\n        .chain(args.iter().cloned())\n        .collect())\n}\n\nfn validate_project_name(name: Option<&str>) -> Result<()> {\n    let Some(name) = name else {\n        return Ok(());\n    };\n    if name.is_empty()\n        || !name\n            .chars()\n            .next()","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/compose.rs#L1027-L1063","documentation":"When the first element of engine_command (or the prefix of command) is an absolute path, resolve_command verifies it names an existing file before using it. If the path does not exist (typo, wrong prefix, dangling symlink, not installed), mise refuses with this error instead of exec'ing a nonexistent binary. Relative program names go through PATH lookup instead and produce the sibling \"command not found\" error.","triggerScenarios":"engine_command = [\"/usr/bin/podman\"] when podman actually lives at /usr/local/bin/podman; the absolute path points to a directory, a symlink whose target is gone, or a binary that was uninstalled/renamed after config was written.","commonSituations":"Copying mise.toml between machines with different install prefixes (Homebrew /usr/local vs /opt/homebrew vs /usr); uninstalling the engine but leaving the config; path typos after manual editing.","solutions":["Find the real location with `command -v podman` and correct the absolute path","Or drop the path and use a bare name (engine_command = [\"podman\"]) so PATH resolution applies","Reinstall the engine if it was removed","Prefer bare names in shared config; reserve absolute paths for machine-local config"],"exampleFix":"# before\nengine_command = [\"/usr/local/bin/podman\"]  # Homebrew Intel path, wrong on Linux\n\n# after\nengine_command = [\"podman\"]","handlingStrategy":"validation","validationCode":"# before apply, confirm every absolute program in the config exists\nfor p in /usr/local/bin/podman /opt/homebrew/bin/docker; do\n  [ -f \"$p\" ] || echo \"configured engine path missing: $p\" >&2\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer bare engine names (\"podman\") over absolute paths in config shared across machines","Keep absolute-path engine_command only in machine-local config files","After uninstalling or relocating an engine, grep mise.toml for its old path"],"tags":["compose","container-engine","path","filesystem"],"backgroundTag":"file-not-found","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}