{"record":{"id":"2bbc6de45b8c4003","repo":"jdx/mise","slug":"install-command-install-command-exited-success","errorCode":null,"errorMessage":"install_command `{install_command}` exited successfully but installed no executable into {}; check that it installs into $MISE_TOOL_INSTALL_PATH and that it fails when the build fails","messagePattern":"install_command `(.+?)` exited successfully but installed no executable into (.+?); check that it installs into \\$MISE_TOOL_INSTALL_PATH and that it fails when the build fails","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/spm.rs","lineNumber":707,"sourceCode":"    }\n    Ok(executables\n        .into_iter()\n        .filter(|e| filter.contains(e))\n        .collect())\n}\n\n/// Verifies that `install_command` actually installed an executable into `bin/`.\n///\n/// A package's install script may exit 0 even when the underlying `swift build`\n/// failed (for example when the script does not use `set -e`), which would\n/// otherwise leave mise reporting a successful install for a directory that has\n/// no runnable tool in it.\nfn verify_install_command_output(install_command: &str, bin_path: &Path) -> eyre::Result<()> {\n    if !file::ls(bin_path)?\n        .iter()\n        .any(|entry| entry.is_file() && file::is_executable(entry))\n    {\n        bail!(\n            \"install_command `{install_command}` exited successfully but installed no executable into {}; check that it installs into $MISE_TOOL_INSTALL_PATH and that it fails when the build fails\",\n            bin_path.display()\n        );\n    }\n    Ok(())\n}\n\n#[derive(Clone, Debug, Eq, PartialEq)]\npub(crate) struct GitProvider {\n    pub api_url: String,\n    pub kind: GitProviderKind,\n}\n\nimpl Default for GitProvider {\n    fn default() -> Self {\n        Self {\n            api_url: github::API_URL.to_string(),\n            kind: GitProviderKind::GitHub,","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/backend/spm.rs#L689-L725","documentation":"After running a custom install_command, mise sanity-checks the target bin directory ($MISE_TOOL_INSTALL_PATH/bin): it must contain at least one executable file. A command that exits 0 but produces nothing (or nothing executable) is treated as a broken install, since most build tools fail loudly on error and silence here usually means the command didn't actually install anything.","triggerScenarios":"install_command script that builds but never copies the binary into $MISE_TOOL_INSTALL_PATH, copies to the wrong directory, or copies a non-executable file; called from run_install_command during install.","commonSituations":"Using `swift build` alone without a copy step, wrong output path (.build/release vs $MISE_TOOL_INSTALL_PATH), or forgetting chmod +x on the copied binary.","solutions":["Make the install_command copy the built executable into $MISE_TOOL_INSTALL_PATH/bin and chmod +x it","Verify the build output path (e.g. .build/release/<tool>) and adjust the copy command","Test the command manually with MISE_TOOL_INSTALL_PATH set to a temp dir to confirm it populates bin/"],"exampleFix":"// before\ninstall_command = \"swift build -c release\"\n\n// after\ninstall_command = \"swift build -c release && install -m 0755 .build/release/mytool \"$MISE_TOOL_INSTALL_PATH/bin/\"\"","handlingStrategy":"validation","validationCode":"# Dry-run the install command locally\nexport MISE_TOOL_INSTALL_PATH=/tmp/spmtest\nrm -rf $MISE_TOOL_INSTALL_PATH && mkdir -p $MISE_TOOL_INSTALL_PATH/bin\nsh -c \"$INSTALL_COMMAND\" && ls -l $MISE_TOOL_INSTALL_PATH/bin  # must show an executable","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always end install_command with an install/copy step into $MISE_TOOL_INSTALL_PATH/bin","Use `install -m 0755` so the executable bit is set","Test the command with a temp MISE_TOOL_INSTALL_PATH before committing config"],"tags":["swift","spm","install-command","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}