{"record":{"id":"2376668f84895473","repo":"jdx/mise","slug":"package-hook-did-not-return-state-for","errorCode":null,"errorMessage":"{} package hook did not return state for '{}'","messagePattern":"(.+?) package hook did not return state for '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/plugin.rs","lineNumber":569,"sourceCode":"                let returned = by_name.get(&request.name);\n                let state = match returned {\n                    Some(pkg) if pkg.state == \"installed\" => {\n                        let installed = pkg.version.clone().unwrap_or_default();\n                        match &request.version {\n                            Some(requested) if requested != &installed => {\n                                PackageState::VersionMismatch { installed }\n                            }\n                            _ => PackageState::Installed { version: installed },\n                        }\n                    }\n                    Some(pkg) if pkg.state == \"missing\" => PackageState::Missing,\n                    Some(pkg) => bail!(\n                        \"{} package hook returned invalid state '{}' for '{}'\",\n                        self.name,\n                        pkg.state,\n                        request.name\n                    ),\n                    None => bail!(\n                        \"{} package hook did not return state for '{}'\",\n                        self.name,\n                        request.name\n                    ),\n                };\n                Ok(PackageStatus {\n                    request: request.clone(),\n                    state,\n                })\n            })\n            .collect()\n    }\n\n    async fn install(&self, pkgs: &[PackageRequest], opts: &InstallOpts) -> Result<()> {\n        if opts.dry_run {\n            return self.action(pkgs, opts, false).await;\n        }\n        let _lock = self.operation_lock()?;","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/plugin.rs#L551-L587","documentation":"After running the plugin's package hook, installed() looks up state for the requested package. If the hook's response contains no entry for that package, mise fails explicitly, because it cannot determine whether the package is installed, missing, or mismatched — information needed by install, upgrade, and prune planning.","triggerScenarios":"The package hook (called from installed via prune_plan, apply_prune_plan, install, or upgrade) returns a list/record that omits the requested package name — e.g. the Lua hook filters it out, matches names case-sensitively, or returns an empty/partial result.","commonSituations":"Plugin hook bug where the queried package name doesn't match the manager's reported name (alias vs real name); hook returns early on error and omits entries; package was uninstalled between listing and check.","solutions":["Fix the plugin's status hook so it always returns an entry for every queried package, matching request names exactly","Update or reinstall the plugin to a version whose hook handles the package correctly","Run the underlying manager's own query (e.g. `brew list --versions <pkg>`) to check the package manually","Check for name mismatches (aliases, case) between the request and what the manager reports"],"exampleFix":"// before (plugin hook returns nothing for 'redis')\n-- hook only reports packages it found installed\n// after (plugin hook Lua)\n-- always emit an entry per requested package\nreturn { { name = \"redis\", state = \"missing\" } }","handlingStrategy":"validation","validationCode":"let resp = run_hook(&req.name)?;\nif !resp.iter().any(|p| p.name == req.name) {\n    /* hook incomplete: treat as missing or fix plugin */\n}","typeGuard":"fn hook_answered(pkgs: &[HookPkg], name: &str) -> bool {\n    pkgs.iter().any(|p| p.name == name)\n}","tryCatchPattern":"match plugin.installed(&req).await {\n    Err(e) if e.to_string().contains(\"did not return state\") => {\n        Ok(PackageStatus { state: PackageState::Missing, ..Default::default() })\n    }\n    other => other,\n}","preventionTips":["Ensure plugin status hooks emit an entry for every requested package, including missing ones","Match package names exactly (beware aliases and case differences between manager output and requests)","Test the hook with both installed and not-installed packages"],"tags":["plugin","empty-result","lua-hook","state"],"backgroundTag":"empty-result-set","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}