{"record":{"id":"d8f3e1c7c696c1e6","repo":"fyne-io/fyne","slug":"eglswapbuffer-failed-n","errorCode":null,"errorMessage":"eglSwapBuffer failed\\n","messagePattern":"eglSwapBuffer failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/driver/mobile/app/x11.c","lineNumber":172,"sourceCode":"\t\t\tonTouchMove((float)ev.xmotion.x, (float)ev.xmotion.y);\n\t\t\tbreak;\n\t\tcase ConfigureNotify:\n\t\t\tonResize(ev.xconfigure.width, ev.xconfigure.height);\n\t\t\tbreak;\n\t\tcase ClientMessage:\n\t\t\tif (wm_delete_window != None && (Atom)ev.xclient.data.l[0] == wm_delete_window) {\n\t\t\t\tonStop();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid\nswapBuffers(void) {\n\tif (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {\n\t\tfprintf(stderr, \"eglSwapBuffer failed\\n\");\n\t\texit(1);\n\t}\n}\n","sourceCodeStart":154,"sourceCodeEnd":176,"githubUrl":"https://github.com/fyne-io/fyne/blob/8860ee95c356385effa5a7be51adb11c6be9d2b6/internal/driver/mobile/app/x11.c#L154-L176","documentation":"Unlike the other x11.c failures, this one fires during the render loop: swapBuffers() calls eglSwapBuffers each frame and exits(1) with 'eglSwapBuffer failed' (the message misspells eglSwapBuffers) when the swap returns EGL_FALSE. That means the surface is no longer swap-able: the window/surface was destroyed, the EGL context was lost (GPU reset, suspend/resume), or the display connection dropped mid-run.","triggerScenarios":"Calling swapBuffers() after the window has been closed/destroyed, after a driver/GPU reset invalidates the context, or while the X display connection is being torn down (session ending, SSH dropping).","commonSituations":"Laptop suspend/resume under the app; closing the window while a frame swap is in flight; driver crashes/recovery (TDR); long-running kiosk apps across display restarts.","solutions":["Restart the application after GPU/driver resets or suspend/resume cycles; the process exits immediately by design","Keep the display connection and window alive for the whole render loop; do not destroy the window from another goroutine/thread mid-swap","Update Mesa/GPU drivers to reduce spurious context loss","If you build the driver, replace exit(1) with an eglMakeCurrent retry or surface recreation on EGL_CONTEXT_LOST"],"exampleFix":"// before (x11.c): any failed swap kills the process\nvoid\nswapBuffers(void) {\n\tif (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {\n\t\tfprintf(stderr, \"eglSwapBuffer failed\\n\");\n\t\texit(1);\n\t}\n}\n\n// after: attempt recovery once before giving up\nvoid\nswapBuffers(void) {\n\tif (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {\n\t\tif (eglGetError() == EGL_CONTEXT_LOST && eglMakeCurrent(e_dpy, e_surf, e_surf, e_ctx))\n\t\t\treturn;\n\t\tfprintf(stderr, \"eglSwapBuffer failed\\n\");\n\t\texit(1);\n\t}\n}","handlingStrategy":"validation","validationCode":"func swapPreflight(w fyne.Window) error {\n\tif w == nil || w.Canvas() == nil {\n\t\treturn fmt.Errorf(\"window/canvas destroyed; cannot swap buffers\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Destroy windows only through the driver's normal lifecycle, never from arbitrary goroutines mid-frame","Expect and handle app exit after suspend/resume or GPU resets; restart the process as recovery","If vendoring this code, patch swapBuffers to retry eglMakeCurrent on EGL_CONTEXT_LOST instead of exiting"],"tags":["c","egl","x11","swapbuffers","context-loss","runtime"],"backgroundTag":null,"analyzedSha":"8860ee95c356385effa5a7be51adb11c6be9d2b6","analyzedAt":"2026-08-15T22:01:51.624Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}