MGS3003: tool not on PATH
os\which could not resolve a command. The tool is not installed, or not
visible to this run - a sandboxed target sees a curated PATH, so "installed on
your machine" and "reachable from here" are different questions.
[MGS3003] "vhs" is not on PATH: exec: "vhs": executable file not found in $PATH
Why this raises instead of returning ""
os\which used to answer "" for a missing command so a magusfile could
branch on os\which(cmd) == "". That put the check on every call site and made
it optional - skip it and the empty string flows straight into an os\exec or
a path join, and the failure surfaces as something unrelated.
Resolution
Wrap it where a missing tool is a case you want to explain. The point of checking at all is to replace a cryptic exec failure with a sentence that says how to fix it:
try {
os\which("vhs");
} catch (e) {
throw "tapes: vhs not found on PATH; install it with `brew install vhs`";
}
If the tool should always be present, do not catch. The raised error already names the command and the reason, which is a better failure than a downstream exec error nobody can trace back.
Pinning the tool instead
A tool a target needs should usually be pinned in mise.toml rather than
assumed. A pinned tool is installed by mise install in CI and resolves the
same way on every machine, which turns this diagnostic from a routine
occurrence into a genuine misconfiguration.
Catching it by code
try {
final p = os\which("docker");
} catch (e) {
if (e["code"] == "MGS3003") {
magus\info("docker is not available; skipping the container checks");
}
}