{"record":{"id":"d7c109bb9f8bf2cc","repo":"slint-ui/slint","slug":"platform-already-initialized","errorCode":null,"errorMessage":"platform already initialized","messagePattern":"platform already initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backends/testing/lib.rs","lineNumber":45,"sourceCode":"pub mod systest;\n\n/// Initialize the testing backend without support for event loop.\n/// This means that each test thread can use its own backend, but global functions that needs\n/// an event loop such as `slint::invoke_from_event_loop` or `Timer`s won't work.\n/// Must be called before any call that would otherwise initialize the rendering backend.\n/// Calling it when the rendering backend is already initialized will panic.\n///\n/// Note that for animations and timers, the changes in the system time will be disregarded.\n/// Instead, use [`mock_elapsed_time()`] to advance the simulate (mock) time Slint uses.\npub fn init_no_event_loop() {\n    i_slint_core::platform::set_platform(Box::new(testing_backend::TestingBackend::new(\n        testing_backend::TestingBackendOptions {\n            mock_time: true,\n            threading: false,\n            ..Default::default()\n        },\n    )))\n    .expect(\"platform already initialized\");\n}\n\n/// Initialize the testing backend with support for simple event loop.\n/// This function can only be called once per process, so make sure to use integration\n/// tests with only one `#[test]` function. (Or in a doc test)\n/// Must be called before any call that would otherwise initialize the rendering backend.\n/// Calling it when the rendering backend is already initialized will panic.\n///\n/// Note that for animations and timers, the changes in the system time will be disregarded.\n/// Instead, use [`mock_elapsed_time()`] to advance the simulate (mock) time Slint uses.\npub fn init_integration_test_with_mock_time() {\n    i_slint_core::platform::set_platform(Box::new(testing_backend::TestingBackend::new(\n        testing_backend::TestingBackendOptions {\n            mock_time: true,\n            threading: true,\n            ..Default::default()\n        },\n    )))","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/internal/backends/testing/lib.rs#L27-L63","documentation":"`init_no_event_loop` in the testing backend installs the testing platform via `set_platform`, which can only succeed once per process. If a platform is already installed (a previous test init, or any code that triggered backend initialization), the call returns an error and the `.expect(\"platform already initialized\")` panics. Slint allows exactly one platform initialization per process lifetime.","triggerScenarios":"Calling `slint_testing::init_no_event_loop()` (or the related init_integration_test_* functions) more than once in the same process, e.g. multiple #[test] functions in one test binary, or after something else already created a window/backend.","commonSituations":"Integration test crates with several #[test] fns (each test binary runs them in one process); combining testing-backend init with a doc test; an earlier test created a Slint component before the init call, auto-initializing the platform.","solutions":["Restructure tests so the whole binary has one init: put multiple scenarios inside a single #[test] function, as the function's docs recommend.","Use a shared `std::sync::Once` guard around the init call so it executes exactly once per process.","Split tests into separate binaries (one #[test] per integration test file) so each process initializes the platform once.","Alternatively call `init_integration_test_with_mock_time()`/`_with_system_time()`, which are designed for the same one-time role — but still only once."],"exampleFix":"// before\n#[test] fn a() { slint_testing::init_no_event_loop(); /* ok */ }\n#[test] fn b() { slint_testing::init_no_event_loop(); /* panics */ }\n\n// after: one init per process\nstatic INIT: std::sync::Once = std::sync::Once::new();\nfn ensure_init() {\n    INIT.call_once(|| slint_testing::init_no_event_loop());\n}\n#[test] fn a() { ensure_init(); /* ... */ }\n#[test] fn b() { ensure_init(); /* ... */ }","handlingStrategy":"validation","validationCode":"use std::sync::Once;\nstatic TEST_INIT: Once = Once::new();\npub fn ensure_testing_init() {\n    TEST_INIT.call_once(|| slint_testing::init_no_event_loop());\n}","typeGuard":null,"tryCatchPattern":"// tolerate repeated init at call site\nif TEST_INIT.is_completed() { return; }\nslint_testing::init_no_event_loop();","preventionTips":["Guard all testing-backend init behind a std::sync::Once","Keep one #[test] function per integration test binary","Never create Slint components before the testing backend init runs","Avoid mixing doc tests and unit tests that each initialize the platform in one process"],"tags":["testing","platform","initialization","event-loop"],"backgroundTag":"invalid-state-transition","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}