Repository navigation
obs-websocket: Report a missing program or preview scene as null - #1256
Merged
Merged
Conversation
…ogram scene
In Studio Mode the frontend keeps the program scene as a weak reference,
so once that scene is removed (RemoveScene, or the scene list),
obs_frontend_get_current_scene() returns NULL. GetSceneList already
reports this as a null currentProgramSceneName. GetCurrentProgramScene
puts the NULL name straight into a json string, which throws
std::logic_error ("basic_string: construction from null is not valid")
on the websocket thread, and OBS aborts. GetCurrentPreviewScene has the
same shape.
test_ws_current_scene_removed builds the plugin's scene requests against
libobs and answers the frontend calls from weak references to a real
scene, as OBSStudioAPI does in Studio Mode. With the scene in place both
requests report it (guards); after the scene is removed both requests
throw instead of answering with null names: 2 of 4 cases fail.
Refs obs-rust#1254.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the submodule to the fork fix "requesthandler: Report a missing program or preview scene as null" (port of obsproject/obs-websocket#1353 by andrewsoncha, extended to the preview scene). GetCurrentProgramScene after the program scene was removed in Studio Mode aborted OBS; it now answers with null names and UUIDs, as GetSceneList does. GetCurrentPreviewScene gets the same check. Nothing changes while the scene exists. test_ws_current_scene_removed passes 4 of 4. Fixes obs-rust#1254. Co-Authored-By: andrewsoncha <65234283+andrewsoncha@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zackees
approved these changes
Oct 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1254
What and why
GetCurrentProgramSceneno longer aborts OBS when there is no program scene. It answers with null names and UUIDs instead, asGetSceneListalready does (upstream obsproject/obs-websocket#1349, reported by stevets).OBSBasic::programScene).obs_frontend_get_current_scene()returnsobs_weak_source_get_source()of it (frontend/OBSStudioAPI.cpp.hppline 54), which is NULL once that scene is removed and destroyed.GetCurrentProgramScene()(plugins/obs-websocket/src/requesthandler/RequestHandler_Scenes.cpp) putobs_source_get_name(NULL)into a json string. That throwsstd::logic_error("basic_string: construction from null is not valid") on the websocket thread, and OBS aborts (SIGSEGV instrlenon macOS). One client sendingRemoveScenefor the program scene and thenGetCurrentProgramScenetakes OBS down, in the middle of a stream or a recording.sceneName,sceneUuid,currentProgramSceneNameandcurrentProgramSceneUuidarenullwhen there is no program scene.GetCurrentPreviewScenehas the same unchecked shape and gets the same check. This PR moves the submodule to it.GetSceneListhas reported the same state ascurrentProgramSceneName: nullall along, so clients already see null there.Reproduced in release v0.1.0-beta.20261014 (AppImage) and on master bbf55a0. Headless: private Xvfb, fresh HOME,
dbus-run-session,--multi. One websocket client sendsSetStudioModeEnabledtrue,CreateScene"victim",SetCurrentProgramScene"victim",RemoveScene"victim", waits 1 s, then sendsGetSceneList,GetCurrentProgramScene, andSetCurrentProgramScene"Scene" +GetCurrentProgramScene.GetSceneListprogram after the removalGetCurrentProgramSceneterminate called after throwing an instance of 'std::logic_error'/basic_string: construction from null is not validSetCurrentProgramScene"Scene" +GetCurrentProgramSceneRemoving the preview scene instead is fine everywhere: the frontend moves the preview to another scene.
RED → GREEN
test/cmocka: Add failing test for GetCurrentProgramScene without a program scene.test_ws_current_scene_removedbuilds the plugin's scene requests (RequestHandler_Scenes.cppwith Request.cpp and the Utils helpers it calls) against libobs, the waytest_ws_transform_boundsdoes. The frontend calls answer from weak references to a real scene, asOBSStudioAPIdoes in Studio Mode. The guardsprogram_scene_reportedandpreview_scene_reportedpass.removed_program_scene_reported_nullandremoved_preview_scene_reported_nullfail withGetCurrentProgramScene threw 'basic_string: construction from null is not valid'(the same for the preview). That is 2 of 4 failing, withENABLE_RUST_LIBOBSOFF and ON. Linux only, like the other websocket request tests. The cases skip without a display (checked withDISPLAYunset).plugins/obs-websocketfrom d79d2c2 to 0d663ee, the merged fork fix (requesthandler: Report a missing program or preview scene as null obs-websocket#17; same tree as the commit tested here). 4 of 4 pass in both lanes. Full OBS build (frontend + obs-websocket) in both lanes. Full ctest -j4 (private Xvfb,dbus-run-session, fresh HOME, systemlibobs-openglmasked, TMPDIR unset): 282/282 in both lanes. Every PipeWire/PulseAudio test ran. Skipped onlyopen_crashes_without_obs_core(both lanes) and, in the Rust lane,test_startup_shutdown_cycles: its one case skips when one of its 2000obs_startup()calls fails under load, and it passed on a rerun alone. clang-format 22.1 and gersemi 0.25.0 clean.Checklist
master-W..., ratchets): noneAI note: Claude Code (Claude Opus 5.5) wrote the code, the test, the commit messages and this text under the submitter's direction, and ran the tests above on the submitter's machines.
🤖 Generated with Claude Code