{"record":{"id":"110aa7efdb6e2b5a","repo":"zellij-org/zellij","slug":"failed-to-get-running-plugin","errorCode":null,"errorMessage":"Failed to get running plugin","messagePattern":"Failed to get running plugin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"zellij-server/src/plugins/wasm_bridge.rs","lineNumber":1754,"sourceCode":"            };\n        }\n    }\n    pub fn cache_plugin_permissions(\n        &mut self,\n        plugin_id: PluginId,\n        client_id: Option<ClientId>,\n        permissions: Vec<PermissionType>,\n        status: PermissionStatus,\n        cache_path: Option<PathBuf>,\n    ) -> Result<()> {\n        let err_context = || format!(\"Failed to write plugin permission {plugin_id}\");\n\n        let running_plugin = self\n            .plugin_map\n            .lock()\n            .unwrap()\n            .get_running_plugin(plugin_id, client_id)\n            .ok_or_else(|| anyhow!(\"Failed to get running plugin\"))?;\n\n        let mut running_plugin = running_plugin.lock().unwrap();\n\n        let permissions = if status == PermissionStatus::Granted {\n            permissions\n        } else {\n            vec![]\n        };\n\n        running_plugin\n            .store\n            .data_mut()\n            .set_permissions(HashSet::from_iter(permissions.clone()));\n\n        let mut permission_cache = PermissionCache::from_path_or_default(cache_path);\n        permission_cache.cache(\n            running_plugin.store.data().plugin.location.to_string(),\n            permissions,","sourceCodeStart":1736,"sourceCodeEnd":1772,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-server/src/plugins/wasm_bridge.rs#L1736-L1772","documentation":"Thrown in the plugin-permission write path (wasm_bridge.rs) when PluginMap::get_running_plugin returns None for the given (plugin_id, client_id). The map stores assets per (plugin_id, client_id) pair, so the lookup fails when that combination was never registered or was already unloaded.","triggerScenarios":"A permission request resolves after the plugin was unloaded (UninstallPlugin/Unload instruction raced the permission grant), or the request is answered with a client_id different from the one the plugin instance is keyed under (e.g. permission granted from another connected client that has no instance of the plugin).","commonSituations":"Granting a permission dialog after the plugin pane was closed or the session is shutting down; multi-client sessions where the permission reply arrives on a different client; plugin auto-reload while a permission prompt is open.","solutions":["Grant or deny the permission prompt before closing/reloading the plugin pane","In multi-client setups, answer the prompt from the client that opened the plugin","If developing against this API, treat a None from get_running_plugin as 'plugin gone' and skip the write instead of propagating an error","Retry the plugin action after re-granting; the plugin will re-request permission on its fresh instance"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn plugin_alive(map: &PluginMap, plugin_id: u32, client_id: u16) -> bool {\n    map.get_running_plugin(plugin_id, Some(client_id)).is_some()\n}","tryCatchPattern":"match self.plugin_map.lock().unwrap().get_running_plugin(plugin_id, client_id) {\n    Some(running) => { /* write permission */ },\n    None => return Ok(()), // plugin gone; nothing to update\n}","preventionTips":["Resolve permission prompts before closing or reloading the plugin pane","In multi-client sessions, answer prompts from the client that hosts the plugin"],"tags":["plugin","permissions","lifecycle","race","wasm-bridge"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}