Repository navigation
Description
Two upstream OBS bugs in the Plugin Manager, both reported by FiniteSingularity: obsproject/obs-studio#13948 (Safe Mode lists third-party plugins as Missing) and obsproject/obs-studio#14005 (the trash button for a Missing plugin doesn't always remove it). Warchamp7 fixed them upstream in obsproject/obs-studio#14001 and obsproject/obs-studio#14008, both merged on 2026-10-08. Neither fix is in obs-rust yet. One issue for both because #14008 builds on #14001 and they touch the same three files.
Location
frontend/plugin-manager/PluginManager.cpploadAllPlugins()(line 96) only setsloadState_insideif (loadMode_ == Mode::Full). Safe Mode and--only-bundled-pluginsload withMode::CoreOnly(frontend/OBSApp.cppline 1963), soloadState_keeps its defaultState::Failure(PluginManager.hppline 53).OBSApp::handlePluginLoadState()(OBSApp.cppline 1969) then opens the modal "Plugin Errors" box (handlePluginFailure(),exec()) after the main window loads, on every such start.frontend/plugin-manager/PluginManagerWindow.cppsetupInstalledPage()(line 135): a cached plugin that is not loaded isStatus::Missing. In both modes that is every third-party plugin. Each such row gets a trash button that deletes the plugin's saved entry (enabled state and the types it provides).- Same file, line 164: each row's
Entrykeeps&metadata, a pointer into the window'smodules_vector. The trash handler (line 207) looks its entry up by address and callsmodules_.erase(), which shifts every later element down one slot. After that, each later row points at the next plugin: its trash button removes the wrong entry, and its toggle (InstalledPluginRow.cppline 135,metadata->enabled = checked) turns a different plugin on or off.PluginManager::open()saves the result toplugin_manager/modules.jsonwhen the window is saved.
Class
Logic error (a state that is never set) and use of invalidated pointers. The modal dialog blocks unattended starts, and the Plugin Manager can delete or disable the wrong plugin's settings. No crash was seen.
How it is reached
--safe-mode, Help > Restart in Safe Mode, the crash dialog's "Launch in Safe Mode", or--only-bundled-plugins: the "Plugin Errors" dialog ("OBS Studio was not able to load all third-party plugins") appears although nothing failed. Tools > Plugin Manager then lists every third-party plugin as Missing, with a trash button.- Normal start with two or more Missing entries (plugins that were uninstalled): remove one, then use the trash button or toggle of any row after it.
Reproduced in 0.1.0-beta.20261014
The released AppImage (built from 9e2325e), headless (private Xvfb and D-Bus), one profile across the starts, a small test plugin (it loads and does nothing) in the user plugin folder. The dialog was detected by its window title.
| Start | "Plugin Errors" dialog | Plugin Manager | SIGTERM while it is up |
|---|---|---|---|
| normal (control, twice) | none | - | quits in 0.2 s |
--only-bundled-plugins |
shown | the test plugin and every other third-party plugin under "Missing", each with a trash button | OBS still running after 20 s |
--safe-mode |
shown | same, under the "All plugins temporarily disabled by Safe Mode" label | - |
For #14005, plugin_manager/modules.json listed three plugins that do not exist (ghost-a, ghost-b, ghost-c, so they show as Missing) before two that load (the test plugin and a second test plugin that drives the window). In the Plugin Manager, a test plugin clicked the way a user does: the trash button of ghost-a, the toggle of the first test plugin (off), the trash button of ghost-c, then Save.
| Expected | 0.1.0-beta.20261014 | |
|---|---|---|
| ghost-a | removed | removed |
| ghost-c | removed | kept |
| first test plugin | kept, turned off | removed |
| second test plugin | kept, on | turned off |
| restart prompt (a plugin was turned off) | shown | not shown |
Proposed fix and failing test
Port both upstream PRs, crediting Warchamp7 as the author of his commits:
- #14001:
loadAllPlugins()reportsSuccesswhen the mode is notFull. In Safe Mode the Plugin Manager lists the cached plugins as Installed with a "Disabled" chip (no trash button) and shows a notice. - The same for
--only-bundled-plugins(not in #14001), with a notice that names the flag. - #14008: each row keeps a copy of its
ModuleInfo, and the trash button and toggle find their plugin inmodules_by module name. Upstream,isEnabledPluginsChanged()still reads the rows' copies, which never change, so turning a plugin off no longer shows the restart notice or asks to restart. Readmodules_there instead.
RED test: test_plugin_manager (new, cmocka + Qt Widgets on the offscreen platform, no display). It builds the real PluginManager, PluginManagerWindow and InstalledPluginRow against stand-ins for the frontend app and the libobs module calls. 5 of 8 cases fail today:
- a core-only load reports
Success; - Safe Mode lists cached plugins as installed and disabled, with no trash button;
--only-bundled-pluginsdoes the same;- removing ghost-a and then ghost-c keeps ghost-b and both loaded plugins;
- after removing ghost-a, turning plugin-x off turns plugin-x off (not plugin-y).
Guards that pass today: a full load still reports a plugin failure; on a normal start a plugin that is gone is still Missing and can be removed; turning a plugin off asks for a restart.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
rdoupe commentedon Oct 16, 2026
Claiming: this issue.
A port of Warchamp7's two upstream fixes (obsproject/obs-studio#14001 and #14008), with his commits credited to him:
test_plugin_managerbuilds the real Plugin Manager sources on Qt's offscreen platform. A core-only load (Safe Mode,--only-bundled-plugins) must report success. In both modes the cached plugins must be listed as installed and disabled, without a trash button. Removing Missing entries must remove the clicked ones, and a toggle after a removal must change its own plugin. Guards cover a full load that reports failures, a real Missing plugin on a normal start, and the restart prompt after a toggle. 5 of 8 fail today.--only-bundled-plugins, and one change to #14008 so that turning a plugin off still asks for a restart.--only-bundled-plugins, and the right rows after removals.rdoupe commentedon Oct 16, 2026
@FiniteSingularity you reported both of these upstream: obsproject/obs-studio#13948 (Safe Mode lists third-party plugins as Missing) and obsproject/obs-studio#14005 (the trash button doesn't always remove a Missing plugin). Heads-up that both are fixed here in obs-rust too. #1080 merged today with a regression test. It ports Warchamp7's upstream fixes (obsproject/obs-studio#14001 and #14008).
What changed:
--only-bundled-pluginsno longer show the "Plugin Errors" dialog. A core-only load never set the load state, so it stayed at its default of "failure". The Plugin Manager now lists the skipped plugins as installed and disabled, under a notice, without the trash button that would delete their saved settings. Upstream handles Safe Mode; here--only-bundled-pluginsgets the same treatment.In our release (0.1.0-beta.20261014), Safe Mode and
--only-bundled-pluginsshowed the dialog on every start. With three Missing entries, removing the first and third removed the first and a loaded plugin, and turning a plugin off after the first removal turned off a different one. With the fix: no dialog, and the right entries removed and toggled.It will be in the next obs-rust daily release after 0.1.0-beta.20261014: https://github.com/obs-rust/obs-studio/releases (Windows, macOS and Linux builds; on Arch it's
obs-studio-rust-gitin the AUR). obs-rust is an AI-assisted fork of OBS.If you get a chance to try it, a reply here on whether Safe Mode and removing several Missing plugins behave for you now would really help.
frontend: Fix the plugin manager in Safe Mode and when removing missiβ¦