{"record":{"id":"d339c82531139bb7","repo":"jdx/mise","slug":"package-hook-returned-invalid-state-for","errorCode":null,"errorMessage":"{} package hook returned invalid state '{}' for '{}'","messagePattern":"(.+?) package hook returned invalid state '(.+?)' for '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/plugin.rs","lineNumber":563,"sourceCode":"            .packages\n            .into_iter()\n            .map(|pkg| (pkg.name.clone(), pkg))\n            .collect();\n        pkgs.iter()\n            .map(|request| {\n                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    }","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/plugin.rs#L545-L581","documentation":"The plugin's check/status hook reports each package's state as a string (installed, missing, etc.). When the hook returns a state string the library doesn't recognize, installed() rejects it explicitly instead of guessing, since an unknown state would corrupt install/prune decisions.","triggerScenarios":"The plugin's package hook (invoked via installed) returns a pkg.state value outside the recognized set (e.g. a typo like 'instaled', a new state string from a newer plugin, or plugin Lua returning an unexpected marker).","commonSituations":"Plugin updated to emit a new state string not yet supported by this mise version; custom/local plugin whose status hook returns ad-hoc state names; Lua hook bug producing a malformed state.","solutions":["Update mise to a version that recognizes the state string the plugin emits (plugin and mise version mismatch)","Fix or roll back the plugin's package hook so it returns only supported states (e.g. 'installed', 'missing', supported variants)","Inspect the plugin's hooks/package_check.lua (or equivalent) for typos in state strings","Report the incompatible plugin to its maintainer if it targets a newer mise schema"],"exampleFix":"// before (plugin hook Lua)\nreturn { state = \"partially-installed\", version = v }\n// after\nreturn { state = \"installed\", version = v }","handlingStrategy":"type-guard","validationCode":"const KNOWN_STATES: [&str; 2] = [\"installed\", \"missing\"];\nif !KNOWN_STATES.contains(&pkg.state.as_str()) { /* reject/fix plugin hook */ }","typeGuard":"fn is_valid_state(pkg: &HookPkg) -> bool {\n    matches!(pkg.state.as_str(), \"installed\" | \"missing\")\n}","tryCatchPattern":"match plugin.installed(&req).await {\n    Err(e) if e.to_string().contains(\"returned invalid state\") => {\n        log_plugin_bug(&e); treat_as_unknown_and_skip()\n    }\n    other => other,\n}","preventionTips":["Keep plugin and mise versions in sync; update both together","Only return documented state strings from custom plugin hooks","Test plugin hooks directly with the manager CLI before wiring them into mise"],"tags":["plugin","unexpected-response","lua-hook","state"],"backgroundTag":"unexpected-response-shape","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"}