{"record":{"id":"9e514260f1e0ef81","repo":"kitao/pyxel","slug":"pyxel-flip-is-not-supported-on-pyxel-web","errorCode":null,"errorMessage":"pyxel.flip is not supported on Pyxel Web","messagePattern":"pyxel\\.flip is not supported on Pyxel Web","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/pyxel-core/src/platform/sdl2/platform_sdl2.rs","lineNumber":544,"sourceCode":"            if remaining_ms <= 0.0 {\n                break;\n            }\n            unsafe { SDL_Delay((remaining_ms as u32 / 2).max(1)) };\n        }\n\n        self.swap_window();\n\n        // Catch up if frames were missed\n        let ticks = self.ticks() as f32;\n        while next_frame_ms <= ticks {\n            next_frame_ms += frame_ms;\n        }\n        self.next_update_ms = Some(next_frame_ms);\n    }\n\n    #[cfg(target_os = \"emscripten\")]\n    pub fn step_frame(&mut self, _fps: u32) {\n        panic!(\"pyxel.flip is not supported on Pyxel Web\");\n    }\n\n    // OpenGL\n\n    pub fn gl_profile(&self) -> GlProfile {\n        let mut value = 0i32;\n        unsafe { SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &raw mut value) };\n\n        if value & SDL_GL_CONTEXT_PROFILE_CORE as i32 != 0 {\n            GlProfile::Gl\n        } else if value & SDL_GL_CONTEXT_PROFILE_ES as i32 != 0 {\n            GlProfile::Gles\n        } else {\n            GlProfile::None\n        }\n    }\n\n    #[cfg(not(target_os = \"emscripten\"))]","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/kitao/pyxel/blob/50f9bd77780c993aca62b5b221766bde5791081d/crates/pyxel-core/src/platform/sdl2/platform_sdl2.rs#L526-L562","documentation":"Pyxel's SDL2 platform intentionally replaces `flip` with a panicking stub when compiled for emscripten (Pyxel Web). Web builds render frames through the browser event loop instead of an explicit SDL surface flip, so calling `pyxel.flip` there is unsupported and aborts the program.","triggerScenarios":"Calling `pyxel.flip()` in code compiled to WebAssembly (cargo build --target wasm32-unknown-emscripten / Pyxel Web runner). The panic fires in the platform's step_frame on the emscripten cfg path.","commonSituations":"Cross-platform code that flips manually on desktop builds but also gets compiled for the Web without cfg-gating; tutorials or samples that use flip unconditionally; porting an existing desktop Pyxel app to Pyxel Web.","solutions":["Remove the `pyxel.flip()` call or wrap it in `#[cfg(not(target_os = \"emscripten\"))]` so it only runs on native builds.","Rely on Pyxel's Web run loop to present frames instead of manual flipping.","If a manual present is needed, use the platform-appropriate API behind a cfg attribute."],"exampleFix":"// before\npyxel.flip();\n// after\n#[cfg(not(target_os = \"emscripten\"))]\npyxel.flip();","handlingStrategy":"try-catch","validationCode":"// guard before calling\nif cfg!(target_os = \"emscripten\") {\n    // web: rendering is handled by the run loop; do not flip\n} else {\n    pyxel.flip();\n}","typeGuard":"fn flip_supported() -> bool {\n    !cfg!(target_os = \"emscripten\")\n}","tryCatchPattern":"// panic in Rust cannot be caught portably here; prevent it instead\nif flip_supported() { pyxel.flip(); }","preventionTips":["Cfg-gate any manual flip/step_frame usage with #[cfg(not(target_os = \"emscripten\"))].","Test Web (wasm32-unknown-emscripten) builds in CI so unsupported calls surface early.","Avoid replicating desktop frame-presentation logic in shared code paths."],"tags":["rust","wasm","emscripten","unsupported-api"],"backgroundTag":"unsupported-platform-api","analyzedSha":"50f9bd77780c993aca62b5b221766bde5791081d","analyzedAt":"2026-09-03T10:27:43.285Z","contentChangedAt":"2026-09-03T10:27:43.285Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}