{"record":{"id":"9fa25c153acf9bb4","repo":"jdx/mise","slug":"install-command-must-be-a-non-empty-string","errorCode":null,"errorMessage":"install_command must be a non-empty string","messagePattern":"install_command must be a non-empty string","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/backend/spm.rs","lineNumber":142,"sourceCode":"                .filter_map(|v| v.as_str().map(|s| s.trim().to_string()))\n                .filter(|s| !s.is_empty())\n                .collect(),\n            toml::Value::String(s) => s\n                .split(',')\n                .map(|s| s.trim().to_string())\n                .filter(|s| !s.is_empty())\n                .collect(),\n            _ => return None,\n        };\n        if bins.is_empty() { None } else { Some(bins) }\n    }\n\n    fn install_command(&self) -> eyre::Result<Option<String>> {\n        let Some(value) = self.values.raw().opts.get(\"install_command\") else {\n            return Ok(None);\n        };\n        let Some(command) = value.as_str() else {\n            bail!(\"install_command must be a non-empty string\");\n        };\n        let command = command.trim();\n        if command.is_empty() {\n            bail!(\"install_command must be a non-empty string\");\n        }\n        Ok(Some(command.to_string()))\n    }\n\n    fn source_install_command(&self) -> eyre::Result<Option<String>> {\n        let command = self.install_command()?;\n        if command.is_some() && self.filter_bins().is_some() {\n            bail!(\"install_command cannot be used with filter_bins\");\n        }\n        Ok(command)\n    }\n}\n\n#[async_trait]","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/backend/spm.rs#L124-L160","documentation":"The spm backend's `install_command` option must be a TOML string. This variant of the error is thrown when the option exists but is not a string at all — an array, table, integer, or boolean.","triggerScenarios":"Writing `install_command = [\"make\", \"install\"]` or `install_command = { cmd = \"make install\" }` in a spm tool entry; the value is fetched raw from opts and as_str() is attempted before any trimming.","commonSituations":"Porting a task-style array command syntax into a tool option, or assuming install_command accepts argv arrays like some other config keys.","solutions":["Provide a single shell string: `install_command = \"make install\"`","Put complex commands in one string and rely on shell invocation, or move logic to a script the string calls"],"exampleFix":"# before\n[tools.\"spm:foo/bar\"]\nversion = \"1.0.0\"\ninstall_command = [\"make\", \"install\"]\n\n# after\n[tools.\"spm:foo/bar\"]\nversion = \"1.0.0\"\ninstall_command = \"make install\"","handlingStrategy":"validation","validationCode":"! grep -RnE 'install_command[[:space:]]*=[[:space:]]*[\\[{]' mise.toml","typeGuard":"fn is_string_option(v: &toml::Value) -> bool { v.is_str() }","tryCatchPattern":null,"preventionTips":["install_command is a single string; keep argv arrays out of tool options","Prefer \"cmd arg1 arg2\" strings or call a script"],"tags":["spm","swift","config-validation","mise-toml"],"backgroundTag":"config-validation-failed","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}